2011-11-26 18 views
13

Tengo una ComboBox con la plantilla bastante complejo para los elementos individuales, que incluye dos imágenes y varias líneas de texto:plantilla diferente para los elementos de la lista desplegable del cuadro combinado y de elemento seleccionado

enter image description here

Sin embargo, el elemento seleccionado en el ComboBox no se muestra correctamente, porque el espacio vertical es demasiado limitado (no puedo hacerlo más alto, porque forma parte de un ToolBar).

¿Cómo puedo hacer que el ComboBox utilice una plantilla diferente para el elemento que se muestra en el ComboBox sí mismo? (la representación predeterminada de ToString sería suficiente)

¡Gracias!

+0

Es usar DataTemplateSelector que hacer el truco para usted o que busca otro soluion? Tal vez no me pregunte ¿verdad? – sll

+0

@sll No creo que DataTemplateSelector pueda hacer esto (aunque no lo intenté), IIRC se evalúa solo cuando se cargan los artículos. De todos modos, preferiría una solución más simple que no implique una clase para cada ComboBox que creo (habrá varios de ellos). –

+0

Ok, ¿qué estás tratando de lograr? ¿Representación de IU diferente para artículos según algunos criterios? – sll

Respuesta

27

El elemento seleccionado (en el ComboBox sí mismo, no en el menú desplegable) no está dentro de un ComboBoxItem lo que puede hacer algo como esto:

<ComboBox.ItemTemplate> 
    <DataTemplate> 
     <ContentControl Content="{Binding}"> 
      <ContentControl.Style> 
       <Style TargetType="{x:Type ContentControl}"> 
        <!-- Complex default template --> 
        <Setter Property="ContentTemplate"> 
         <Setter.Value> 
          <DataTemplate> 
           <Image Source="{Binding XPath=media:thumbnail/@url}" Width="100" Height="100" /> 
          </DataTemplate> 
         </Setter.Value> 
        </Setter> 
        <Style.Triggers> 
         <!-- Simple selection box template --> 
         <DataTrigger 
           Binding="{Binding RelativeSource={RelativeSource AncestorType=ComboBoxItem}}" 
           Value="{x:Null}"> 
          <Setter Property="ContentTemplate"> 
           <Setter.Value> 
            <DataTemplate> 
             <TextBlock Text="{Binding XPath=title}" /> 
            </DataTemplate> 
           </Setter.Value> 
          </Setter> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </ContentControl.Style> 
     </ContentControl> 
    </DataTemplate> 
</ComboBox.ItemTemplate> 

(Editar: Tenga en cuenta que la unión en el El cuadro de selección arrojará errores porque no se encuentra el RelativeSource. Hay varias opciones de eludir esto, uno es un convertidor de valor personalizado que devuelve true o false dependiendo de si el ancestro existe (caminar manualmente en árbol).)

+0

¡Gracias, funciona genial! –

+0

De nada, me alegro de que haya ayudado :) –

+0

¡Genial! ¡Gracias! Ymmd :) – pr0gg3r

5

Estaba buscando un estándar (no hacky y sin errores de enlace) solución a este problema. Y lo encontré here: usando DataTemplateSelector.

Es la misma idea que en @H.B. answer: consultar siempre que haya un ComboBoxItem como padre en el árbol visual.

public class ComboBoxItemTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate SelectedTemplate { get; set; } 
    public DataTemplate DropDownTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     while (container != null) 
     { 
      container = VisualTreeHelper.GetParent(container); 
      if (container is ComboBoxItem) 
       return DropDownTemplate; 
     } 
     return SelectedTemplate; 
    } 
} 

Uso:

<ComboBox.ItemTemplateSelector> 
    <local:ComboBoxItemTemplateSelector> 
     <local:ComboBoxItemTemplateSelector.SelectedTemplate> 
      <DataTemplate> 
       ... simple template for selected item 
      </DataTemplate> 
     </local:ComboBoxItemTemplateSelector.SelectedTemplate> 
     <local:ComboBoxItemTemplateSelector.DropDownTemplate> 
      <DataTemplate> 
       ... complex template used by dropdown items 
      </DataTemplate> 
     </local:ComboBoxItemTemplateSelector.DropDownTemplate> 
    </local:ComboBoxItemTemplateSelector> 
</ComboBox.ItemTemplateSelector> 
Cuestiones relacionadas