Comment puis-je fournir plusieurs conditions pour le déclencheur de données dans WPF?
Comment puis-je fournir plusieurs conditions pour le déclencheur de données dans WPF?
Réponses:
Utiliser le type MultiDataTrigger
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=State}" Value="WA">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=Name}" Value="Portland" />
<Condition Binding="{Binding Path=State}" Value="OR" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="Cyan" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
@jasonk - si vous voulez avoir "ou" alors annulez toutes les conditions depuis (A et B) <=> ~ (~ A ou ~ B)
mais si vous avez des valeurs autres que booléennes, essayez d'utiliser des convertisseurs de type:
<MultiDataTrigger.Conditions>
<Condition Value="True">
<Condition.Binding>
<MultiBinding Converter="{StaticResource conditionConverter}">
<Binding Path="Name" />
<Binding Path="State" />
</MultiBinding>
</Condition.Binding>
<Setter Property="Background" Value="Cyan" />
</Condition>
</MultiDataTrigger.Conditions>
vous pouvez utiliser les valeurs de la méthode Convert comme vous le souhaitez pour produire une condition qui vous convient.
conditionConverter
? Comment spécifions-nous "Portland" et "OU" comme nos deux or
options dans cet exemple?
Pour élaborer sur la réponse de @ serine et illustrer le travail avec une condition multi-valeurs non triviale: j'avais besoin d'afficher une superposition "dim-out" sur un élément pour la condition booléenne NOT a AND (b OR NOT c)
.
Pour le contexte, il s'agit d'une question à «choix multiples». Si l'utilisateur choisit une mauvaise réponse, elle devient désactivée (estompée et ne peut pas être sélectionnée à nouveau). Un agent automatisé a la capacité de se concentrer sur n'importe quel choix particulier pour donner une explication (bordure en surbrillance). Lorsque l'agent se concentre sur un élément, il ne doit pas être grisé même s'il est désactivé . Tous les éléments qui ne sont pas focalisés sont marqués comme non focalisés et doivent être grisés.
La logique de la variation est donc:
NOT IsFocused AND (IsDefocused OR NOT Enabled)
Pour implémenter cette logique, j'ai fait un générique IMultiValueConverter
nommé (maladroitement) pour correspondre à ma logique
// 'P' represents a parenthesis
// ! a && ( b || ! c )
class NOT_a_AND_P_b_OR_NOT_c_P : IMultiValueConverter
{
// redacted [...] for brevity
public object Convert(object[] values, ...)
{
bool a = System.Convert.ToBoolean(values[0]);
bool b = System.Convert.ToBoolean(values[1]);
bool c = System.Convert.ToBoolean(values[2]);
return !a && (b || !c);
}
...
}
Dans le XAML, j'utilise ceci MultiDataTrigger
dans une <Style><Style.Triggers>
ressource
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<!-- when the equation is TRUE ... -->
<Condition Value="True">
<Condition.Binding>
<MultiBinding Converter="{StaticResource NOT_a_AND_P_b_OR_NOT_c_P}">
<!-- NOT IsFocus AND ( IsDefocused OR NOT Enabled ) -->
<Binding Path="IsFocus"/>
<Binding Path="IsDefocused" />
<Binding Path="Enabled" />
</MultiBinding>
</Condition.Binding>
</Condition>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<!-- ... show the 'dim-out' overlay -->
<Setter Property="Visibility" Value="Visible" />
</MultiDataTrigger.Setters>
</MultiDataTrigger>
Et par souci d'exhaustivité, mon convertisseur est défini dans un ResourceDictionary
<ResourceDictionary xmlns:conv="clr-namespace:My.Converters" ...>
<conv:NOT_a_AND_P_b_OR_NOT_c_P x:Key="NOT_a_AND_P_b_OR_NOT_c_P" />
</ResourceDictionary>
CETTE RÉPONSE EST POUR LES ANIMATIONS UNIQUEMENT
Si vous souhaitez implémenter la logique AND, vous devez utiliser MultiTrigger, voici un exemple:
Supposons que nous voulions faire des actions si la propriété Text = "" (chaîne vide) AND IsKeyboardFocused = "False", alors votre code doit ressembler à ceci:
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Text" Value="" />
<Condition Property="IsKeyboardFocused" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<!-- Your actions here -->
</MultiTrigger.EnterActions>
</MultiTrigger>
Si vous souhaitez implémenter la logique OR, il existe plusieurs façons, et cela dépend de ce que vous essayez de faire:
La première option consiste à utiliser plusieurs déclencheurs.
Donc, supposons que vous vouliez faire quelque chose si Text = "" OU IsKeyboardFocused = "False",
alors votre code devrait ressembler à ceci:
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border"
Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
Mais le problème est que vais-je faire si je veux faire quelque chose si soit Text ISN'T null OU IsKeyboard = "True"? Ceci peut être réalisé par la deuxième approche:
rappelez la règle de De Morgan, qui dit! (! X &&! Y) = x || y.
Nous allons donc l'utiliser pour résoudre le problème précédent, en écrivant un déclencheur multiple qu'il est déclenché lorsque Text = "" et IsKeyboard = "True", et nous ferons nos actions dans EXIT ACTIONS , comme ceci:
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Text" Value="" />
<Condition Property="IsKeyboardFocused" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.ExitActions>
<!-- Do something here -->
</MultiTrigger.ExitActions>
</MultiTrigger>