在 ListBoxItem.ContentTemplate 中使用 ContentPresenter 是否有任何问题?

发布于 2024-10-01 13:04:12 字数 889 浏览 5 评论 0原文

我的 ListBoxItem.ContentTemplate 中的 ContentPresenter 似乎导致 Visual Studio 崩溃?

<ListBox>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <DockPanel>
                            <TextBlock><ContentPresenter /></TextBlock>
                        </DockPanel>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBoxItem Content="Hello" />
    <ListBoxItem Content="World" />
</ListBox>

或者也许我使用 ContentPresenter 错误?基本上,我希望文本“你好,世界”进入那些内容演示者中

It seems like having a ContentPresenter in my ListBoxItem.ContentTemplate is causing Visual Studio to crash?

<ListBox>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <DockPanel>
                            <TextBlock><ContentPresenter /></TextBlock>
                        </DockPanel>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBoxItem Content="Hello" />
    <ListBoxItem Content="World" />
</ListBox>

Or maybe I am using ContentPresenter wrong? Basically, I want the text hello, world to go into those content presenters

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

回梦 2024-10-08 13:04:12

在 UI 生成期间,ListBox 的 ItemTemplate 将复制到 ListBoxItem 的 ContentTemplate。这意味着您的代码相当于以下内容。

<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <DockPanel>
                <TextBlock><ContentPresenter /></TextBlock>
            </DockPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBoxItem Content="Hello" />
    <ListBoxItem Content="World" />
</ListBox>

但是,您直接添加 ListBoxItems,因此这不是 100% 正确。
(对于已属于 ItemsControl 容器类型的项目,将忽略 ItemTemplate 和 ItemTemplateSelector;Type='ListBoxItem')

详细说明 Visual Studio 崩溃的原因。首先,它只会在填充 ListBox 后崩溃,因此只有在直接在 Xaml 中添加 ListBoxItem 时才会发生这种情况(您的应用程序仍然会崩溃,但 VS 不会崩溃)。 ContentPresenter 是 ListBox 模板插入 ContentTemplate 的地方。因此,如果我们有这个

<Style TargetType="ListBoxItem">           
    <Setter Property="ContentTemplate">           
        <Setter.Value>           
            <DataTemplate>           
                <TextBlock><ContentPresenter /></TextBlock>
            </DataTemplate>           
        </Setter.Value>           
    </Setter>           
</Style>

并且我们不更改模板,那么它看起来像这样(缩短版本),

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="ListBoxItem">
            <ContentPresenter/>
        </ControlTemplate>
    </Setter.Value>
</Setter>

我们将得到

<ContentPresenter/> -> <TextBlock><ContentPresenter /></TextBlock> ->
<TextBlock><TextBlock><ContentPresenter /></TextBlock></TextBlock>  

等等。它永远不会停止,并且 Visual Studio 会崩溃。如果我们将模板更改为此,

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="ListBoxItem">
            <TextBlock Text="No ContentPresenter Here"/>
        </ControlTemplate>
    </Setter.Value>
</Setter>

我们就不会崩溃,因为 ContentPresenter 从未被使用过。
(想想我在尝试这个时让 Studio 崩溃了十几次:)

所以在你的情况下,你应该使用 Template 而不是 ContentTemplate。

<ListBox>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <DockPanel>
                            <TextBlock><ContentPresenter /></TextBlock>
                        </DockPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBoxItem Content="Hello" />
    <ListBoxItem Content="World" />
</ListBox>

The ItemTemplate of a ListBox is copied to the ContentTemplate of a ListBoxItem during UI generation. Meaning that your code is equivalent to the following.

<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <DockPanel>
                <TextBlock><ContentPresenter /></TextBlock>
            </DockPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBoxItem Content="Hello" />
    <ListBoxItem Content="World" />
</ListBox>

However, you're adding the ListBoxItems directly so this is not 100% true.
(ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type; Type='ListBoxItem')

To elaborate on why Visual Studio crashes. First, it only crashes once the ListBox is being populated so this will only happend when adding ListBoxItem's directly in Xaml (Your app will still crash but not VS). The ContentPresenter is the place where the Template for the ListBox is inserting the ContentTemplate. So if we have this

<Style TargetType="ListBoxItem">           
    <Setter Property="ContentTemplate">           
        <Setter.Value>           
            <DataTemplate>           
                <TextBlock><ContentPresenter /></TextBlock>
            </DataTemplate>           
        </Setter.Value>           
    </Setter>           
</Style>

and we don't change the Template so it looks something like this (shortend version)

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="ListBoxItem">
            <ContentPresenter/>
        </ControlTemplate>
    </Setter.Value>
</Setter>

We will get

<ContentPresenter/> -> <TextBlock><ContentPresenter /></TextBlock> ->
<TextBlock><TextBlock><ContentPresenter /></TextBlock></TextBlock>  

and so on. It never stops, and Visual Studio crashes. If we change the Template to this

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="ListBoxItem">
            <TextBlock Text="No ContentPresenter Here"/>
        </ControlTemplate>
    </Setter.Value>
</Setter>

we get no crash since the ContentPresenter is never used.
(Think I crashed Studio a dozen times while trying this out :)

So in your case, you should use Template instead of ContentTemplate.

<ListBox>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <DockPanel>
                            <TextBlock><ContentPresenter /></TextBlock>
                        </DockPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBoxItem Content="Hello" />
    <ListBoxItem Content="World" />
</ListBox>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文