2009-03-02 18 views
39

NOTA He pedido a la pregunta relacionada: How to combine DataTrigger and EventTrigger?WPF - ¿Cómo combinar DataTrigger y Trigger?

que tienen un cuadro de lista que contiene varios elementos. La clase del elemento implementa INotifyPropertyChanged y tiene una propiedad IsAvailable. Uso esa propiedad para indicar opciones no disponibles en la lista usando un color diferente.

Sin embargo, si un elemento seleccionado no está disponible, entonces el color de primer plano debe ser de color rojo.

<ListBox> 
    <ListBox.Resources> 
    <DataTemplate DataType="{x:Type local:InstitutionViewModel}"> 
     <TextBlock Name="Name" Text="{Binding Name}"/> 
     <DataTemplate.Triggers> 
     <DataTrigger Binding="{Binding IsAvailable}" Value="False"> 
      <Setter TargetName="Name" Property="Foreground" Value="#888"/> 
     </DataTrigger> 
     </DataTemplate.Triggers> 
    </DataTemplate> 
    </ListBox.Resources> 
</ListBox> 

Utilizo el disparador de datos anterior para atenuar los elementos no disponibles.

El problema que estoy enfrentando es que el hecho de que se selecciona el elemento no tiene nada que ver con los datos subyacentes a que está obligada la plantilla. Lo que realmente quiero es algún tipo de disparador múltiple que admita tanto un Trigger normal en una propiedad de dependencia (ListBoxItem.IsSelected) junto con un DataTrigger en el elemento de datos vinculado.

¿Se puede hacer esto sin introducir el concepto de selección en mi modelo de vista?

Para cualquiera que se pregunte por qué no deshabilito los artículos no disponibles, entiendo que es un requisito de la aplicación que las opciones no disponibles se puedan seleccionar. En realidad, hay algunos cuadros de lista, y la selección en un solo efecto, lo que está disponible en los otros. No puedo deshabilitar los elementos, ya que el usuario no podría cambiar de opinión o explorar diferentes combinaciones si los elementos se deshabilitaron según las selecciones anteriores.

Respuesta

51

Para cualquier otra persona que está en contra de este problema, he encontrado una solución que funciona para mí. Por supuesto, todavía estoy interesado en ver otras respuestas interesantes.

Aquí es lo que hice:

<MultiDataTrigger> 
    <MultiDataTrigger.Conditions> 
    <Condition Binding="{Binding 
     RelativeSource={ 
     RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, 
     Path=IsSelected}" Value="True"/> 
    <Condition Binding="{Binding IsAvailable}" Value="False"/> 
    </MultiDataTrigger.Conditions> 
    <Setter TargetName="Name" Property="Foreground" Value="#F00"/> 
</MultiDataTrigger> 

No hay nada especial sobre este ser un disparador de múltiples sin embargo. Si sólo quería el estilo del elemento seleccionado de manera diferente en su plantilla de datos, que puede usar:

<DataTrigger Binding="{Binding 
    RelativeSource={ 
    RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, 
    Path=IsSelected}" Value="True"> 
    <Setter TargetName="Name" Property="Foreground" Value="#888"/> 
</DataTrigger> 
+2

eso es exactamente lo que iba recomendar. Hasta donde yo sé, es la mejor solución. –

+0

acaba de golpear el mismo problema. Excelente punto amigo, se olvidó de la vinculación de fuente relativa. – Stimul8d

+0

excelente! ¡gracias por esto! – Fredrik

9

Para utilizarla con el modo de unión DataGridRow cambio a Self:

Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=... 
Cuestiones relacionadas