Есть ли проблемы с наличием ContentPresenter в ListBoxItem.ContentTemplate? - PullRequest
6 голосов
/ 10 ноября 2010

Кажется, что наличие 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>

Или, может быть, я использую ContentPresenter неправильно? В общем, я хочу, чтобы текст привет, мир вошел в эти доводы контента

1 Ответ

8 голосов
/ 10 ноября 2010

ItemTemplate объекта ListBox копируется в ContentTemplate объекта ListBoxItem во время создания пользовательского интерфейса.Это означает, что ваш код эквивалентен следующему.

<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, поэтому это произойдет только при добавлении ListBoxItem непосредственно в Xaml (ваше приложение все равно будет аварийно завершать работу, но не 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>
...