2009-03-02 7 views
39

HINWEIS Ich habe die damit verbundene Frage gestellt: How to combine DataTrigger and EventTrigger?WPF - Wie kombiniert man DataTrigger und Trigger?

Ich habe ein Listenfeld mehrere Elemente enthält. Die Klasse des Elements implementiert INotifyPropertyChanged und hat eine Eigenschaft IsAvailable. Ich verwende diese Eigenschaft, um nicht verfügbare Optionen in der Liste mit einer anderen Farbe anzuzeigen.

Wenn jedoch ein ausgewähltes Element nicht verfügbar ist, sollte die Vordergrundfarbe rot sein.

<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> 

Ich verwende den obigen Datentrigger, um nicht verfügbare Elemente auszugrauen.

Das Problem, mit dem ich konfrontiert bin, ist, dass die Tatsache, dass das Element ausgewählt ist, nichts mit den zugrunde liegenden Daten zu tun hat, an die die Vorlage gebunden ist. Was ich wirklich will, ist eine Art Multi-Trigger, die sowohl eine normale Trigger auf einer Abhängigkeitseigenschaft (ListBoxItem.IsSelected) zusammen mit einer DataTrigger auf dem gebundenen Datenelement unterstützt.

Kann dies getan werden, ohne das Konzept der Auswahl in mein Ansichtsmodell einzuführen?

Für alle, die sich wundern, warum ich nicht verfügbare Elemente nicht deaktiviere, verstehen Sie, dass es eine Anforderung der Anwendung ist, dass nicht verfügbare Optionen ausgewählt werden können. Es gibt tatsächlich ein paar Listenfelder und Auswahl in einem, was in den anderen verfügbar ist. Ich kann die Elemente nicht deaktivieren, da der Benutzer nicht in der Lage wäre, seine Meinung zu ändern oder verschiedene Kombinationen zu untersuchen, wenn Elemente basierend auf früheren Auswahlen deaktiviert wurden.

Antwort

51

Für jeden, der mit diesem Problem zu tun hat, fand ich eine Lösung, die für mich funktioniert. Natürlich bin ich immer noch daran interessiert, andere interessante Antworten zu sehen.

Hier ist, was ich getan habe:

<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> 

Es gibt nichts besonderes über das obwohl ein Multi-Trigger zu sein. Wenn Sie nur das ausgewählte Element anders in Ihrer Datenvorlage stylen möchten, könnten Sie verwenden:

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

das ist genau das, was ich wollte zu empfehlen. Soweit ich weiß, ist es die beste Lösung. –

+0

genau das gleiche Problem. Ausgezeichneter Punkt, vergaß die relative Quellenbindung. – Stimul8d

+0

ausgezeichnet! Danke dafür! – Fredrik

9

Um es mit DataGridRow Änderung Bindungsmodus zu Self zu verwenden:

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