WPF - Come combinare DataTrigger e Trigger?
-
03-07-2019 - |
Domanda
NOTA Ho posto la domanda correlata: Come combinare DataTrigger ed EventTrigger?
Ho una casella di riepilogo contenente diversi elementi. La classe dell'articolo implementa INotifyPropertyChanged
e ha una proprietà IsAvailable
. Uso quella proprietà per indicare le opzioni non disponibili nell'elenco usando un colore diverso.
Tuttavia, se un elemento selezionato non è disponibile, il colore di primo piano dovrebbe essere rosso.
<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 il trigger di dati sopra per oscurare gli elementi non disponibili.
Il problema che sto affrontando è che il fatto che l'elemento sia selezionato non ha nulla a che fare con i dati sottostanti a cui è associato il modello. Quello che voglio davvero è una sorta di multi-trigger che supporti sia un Trigger
normale su una proprietà di dipendenza ( ListBoxItem.IsSelected
) insieme a un DataTrigger
sull'elemento dati associato.
È possibile farlo senza introdurre il concetto di selezione nel mio modello di visualizzazione?
Per chiunque si chieda perché non disabilito gli elementi non disponibili, capire che è un requisito dell'applicazione che le opzioni non disponibili possano essere selezionate. In realtà ci sono alcune caselle di riepilogo e la selezione in un effetto è disponibile negli altri. Non posso disabilitare gli articoli poiché l'utente non sarebbe in grado di cambiare idea o esplorare combinazioni diverse se gli articoli fossero disabilitati in base a selezioni precedenti.
Soluzione
Per chiunque sia contrario a questo problema, ho trovato una soluzione che funziona per me. Certo, sono ancora interessato a vedere altre risposte interessanti.
Ecco cosa ho fatto:
<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>
Non c'è niente di speciale nel fatto che questo sia un multi trigger. Se volessi semplicemente modificare in modo diverso l'elemento selezionato nel modello di dati, puoi utilizzare:
<DataTrigger Binding="{Binding
RelativeSource={
RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},
Path=IsSelected}" Value="True">
<Setter TargetName="Name" Property="Foreground" Value="#888"/>
</DataTrigger>
Altri suggerimenti
To use it with DataGridRow
change binding mode to Self
:
Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=...