WPF - ¿Cómo combinar Data Trigger y Trigger?
-
03-07-2019 - |
Pregunta
NOTA He hecho la pregunta relacionada: ¿Cómo combinar DataTrigger y EventTrigger?
Tengo un cuadro de lista que contiene varios elementos. La clase del elemento implementa INotifyPropertyChanged
y tiene una propiedad IsAvailable
. Utilizo esa propiedad para indicar las opciones no disponibles en la lista con un color diferente.
Sin embargo, si un elemento seleccionado no está disponible, el color de primer plano debe ser 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>
Uso el activador de datos anterior para atenuar los elementos no disponibles.
El problema al que me enfrento es que el hecho de que el elemento esté seleccionado no tiene nada que ver con los datos subyacentes a los que está vinculada la plantilla. Lo que realmente quiero es algún tipo de disparador múltiple que admita tanto un Trigger
en una propiedad de dependencia ( ListBoxItem.IsSelected
) junto con un DataTrigger
en el elemento de datos enlazado.
¿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 elementos no disponibles, comprenda que es un requisito de la aplicación que se puedan seleccionar las opciones no disponibles. En realidad hay algunos cuadros de lista, y la selección en uno de los efectos está disponible en los otros. No puedo desactivar los elementos, ya que el usuario no podría cambiar de opinión o explorar diferentes combinaciones si los elementos se desactivaron en función de las selecciones anteriores.
Solución
Para cualquier otra persona que se enfrente a este problema, encontré una solución que funciona para mí. Por supuesto, todavía estoy interesado en ver otras respuestas interesantes.
Esto 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>
Sin embargo, no hay nada especial en que sea un disparador múltiple. Si solo desea aplicar un estilo diferente al elemento seleccionado en su plantilla de datos, 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>
Otros consejos
Para usarlo con DataGridRow
cambie el modo de enlace a Self
:
Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=...