2010-11-10 5 views
6

Кажется, что наличие ContentPresenter в моем ListBoxItem.ContentTemplate приводит к сбою Visual Studio?Есть ли проблема с наличием ContentPresenter в ListBoxItem.ContentTemplate?

<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

Попробовал ваш код и он разбился в порядке :) –

+2

Вы не можете использовать ContentPresenter в ContentTemplate, потому что это своего рода рекурсивного кода, ContentPresenter снова загрузить ContentTemplate и ContentTemplate снова загружать ContentPresenter и так далее .. .. –

ответ

8

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> 

и мы не изменим шаблон так это выглядит примерно так (shortend версия)

<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 никогда не используется.
(Думаю, я разбил студию дюжину раз, пытаясь это сделать :)

Так что в вашем случае вы должны использовать Шаблон вместо 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>