2010-11-10 16 views
6

Parece que tener un ContentPresenter en mi ListBoxItem.ContentTemplate está causando la falla de Visual Studio?¿Hay algún problema con tener un ContentPresenter en 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> 

O tal vez estoy usando ContentPresenter mal? Básicamente, quiero el texto hola, mundo para entrar en los presentadores de contenido

+1

intentó su código y se estrelló bien :) –

+2

No se puede utilizar en ContentPresenter ContentTemplate porque es una especie de código recursivo, ContentPresenter volverá a cargar ContentTemplate y ContentTemplate volverá a cargar ContentPresenter y así sucesivamente .. .. –

Respuesta

8

ItemTemplate de un ListBox se copia en el ContentTemplate de un ListBoxItem durante la generación de la interfaz de usuario. Lo que significa que su código es equivalente a lo siguiente.

<ListBox> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <DockPanel> 
       <TextBlock><ContentPresenter /></TextBlock> 
      </DockPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
    <ListBoxItem Content="Hello" /> 
    <ListBoxItem Content="World" /> 
</ListBox> 

Sin embargo, está agregando los ListBoxItems directamente, por lo que esto no es 100% verdadero.
(ItemTemplate y ItemTemplateSelector son ignorados por artículos ya de tipo de contenedor de ItemsControl; tipo = 'ListBoxItem')

Para más detalles sobre por qué Visual Studio se bloquea. En primer lugar, solo se bloquea una vez que se está llenando el ListBox, por lo que esto solo sucederá cuando se agregue ListBoxItem directamente en Xaml (su aplicación todavía se bloqueará pero no VS). ContentPresenter es el lugar donde la Plantilla para ListBox está insertando ContentTemplate. Así que si tenemos este

<Style TargetType="ListBoxItem">   
    <Setter Property="ContentTemplate">   
     <Setter.Value>   
      <DataTemplate>   
       <TextBlock><ContentPresenter /></TextBlock> 
      </DataTemplate>   
     </Setter.Value>   
    </Setter>   
</Style> 

y no cambiamos la plantilla para que se vea algo como esto (versión shortend)

<Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="ListBoxItem"> 
      <ContentPresenter/> 
     </ControlTemplate> 
    </Setter.Value> 
</Setter> 

Obtendremos

<ContentPresenter/> -> <TextBlock><ContentPresenter /></TextBlock> -> 
<TextBlock><TextBlock><ContentPresenter /></TextBlock></TextBlock> 

etc. . Nunca se detiene y Visual Studio se cuelga. Si cambiamos la plantilla a este

<Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="ListBoxItem"> 
      <TextBlock Text="No ContentPresenter Here"/> 
     </ControlTemplate> 
    </Setter.Value> 
</Setter> 

no obtenemos ningún fallo ya que el ContentPresenter nunca se utiliza.
(Creo que me colapsé Studio una docena de veces al probar esto :)

Por lo tanto, en su caso, debe utilizar Template en lugar de 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> 
Cuestiones relacionadas