开发者

Is there any problem with having a ContentPresenter in ListBoxItem.ContentTemplate?

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 C开发者_如何学Pythonontent="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


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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜