在ListBoxItem.ContentTemplate中使用ContentPresenter有什么问题吗?

Jie*_*eng 6 wpf xaml listbox contentpresenter

好像有ContentPresenter我的ListBoxItem.ContentTemplate原因造成的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>
Run Code Online (Sandbox Code Playgroud)

或许我使用ContentPresenter错了?基本上,我希望文本hello,world进入那些内容演示者

Fre*_*lad 8

在UI生成期间,ListBox的ItemTemplate被复制到ListBoxItem的ContentTemplate.这意味着您的代码等同于以下内容.

<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <DockPanel>
                <TextBlock><ContentPresenter /></TextBlock>
            </DockPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBoxItem Content="Hello" />
    <ListBoxItem Content="World" />
</ListBox>
Run Code Online (Sandbox Code Playgroud)

但是,您直接添加ListBoxItems,因此这不是100%true.
(ItemConmplate和ItemTemplateSelector对于ItemsControl的容器类型已经被忽略; 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>
Run Code Online (Sandbox Code Playgroud)

我们不会更改模板,所以它看起来像这样(短版本)

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="ListBoxItem">
            <ContentPresenter/>
        </ControlTemplate>
    </Setter.Value>
</Setter>
Run Code Online (Sandbox Code Playgroud)

我们将得到

<ContentPresenter/> -> <TextBlock><ContentPresenter /></TextBlock> ->
<TextBlock><TextBlock><ContentPresenter /></TextBlock></TextBlock>  
Run Code Online (Sandbox Code Playgroud)

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

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="ListBoxItem">
            <TextBlock Text="No ContentPresenter Here"/>
        </ControlTemplate>
    </Setter.Value>
</Setter>
Run Code Online (Sandbox Code Playgroud)

我们没有崩溃,因为从未使用过ContentPresenter.
(想想我尝试这个时已经撞了几十次了:)

因此,在您的情况下,您应该使用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>
Run Code Online (Sandbox Code Playgroud)