【问题标题】:Is there any problem with having a ContentPresenter in ListBoxItem.ContentTemplate?ListBoxItem.ContentTemplate 中有 ContentPresenter 有什么问题吗?
【发布时间】:2010-11-10 13:43:29
【问题描述】:

似乎在我的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?基本上,我希望文本 hello, world 进入那些内容演示者

【问题讨论】:

  • 试过你的代码,它崩溃了 :)
  • 不能在 ContentTemplate 中使用 ContentPresenter,因为它是一种递归代码,ContentPresenter 会再次加载 ContentTemplate,ContentTemplate 会再次加载 ContentPresenter 等等......

标签: wpf xaml listbox contentpresenter


【解决方案1】:

在 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% 正确的。
(ItemTemplate 和 ItemTemplateSelector 对于已经是 ItemsControl 容器类型的项目被忽略;Type='ListBoxItem')

详细说明 Visual Studio 崩溃的原因。首先,它只会在填充 ListBox 时崩溃,因此只有在直接在 Xaml 中添加 ListBoxItem 时才会发生这种情况(您的应用程序仍然会崩溃,但不会崩溃)。 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    相关资源
    最近更新 更多