如何在 WPF 中为数据触发器提供多个条件?
使用 多数据触发器类型
<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-如果你想得到“ or”,那么从(A 和 B) < = > ~ (~ A 或 ~ B)开始否定所有条件
但是如果您有布尔值以外的值,请尝试使用类型转换器:
<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>
您可以以任何方式使用 Convert 方法中的值来生成适合您的条件。
为了详细说明 @ Serine 的回答并说明如何使用非平凡的多值条件: 我需要在布尔条件 NOT a AND (b OR NOT c)的项上显示“ dim-out”覆盖。
NOT a AND (b OR NOT c)
$(平台目标) $(找到平台目标) $(平台工具集) $(PlatformToolsetVersion) 对于背景,这是一个“多重选择”的问题。如果用户选择了一个错误的答案,它将变成 残疾人(调暗,不能再次选择)。自动代理能够在任何特定的选择上 集中注意力给出解释(边框突出显示)。当代理将焦点集中在一个项目上时,它不应该调暗 即使它被禁用。所有没有聚焦的项目都标记为 注意力不集中,应该调暗。 因此,变暗的逻辑是: $(PostBuildEventUseInBuild) NOT IsFocused AND (IsDefocused OR NOT Enabled)
对于背景,这是一个“多重选择”的问题。如果用户选择了一个错误的答案,它将变成 残疾人(调暗,不能再次选择)。自动代理能够在任何特定的选择上 集中注意力给出解释(边框突出显示)。当代理将焦点集中在一个项目上时,它不应该调暗 即使它被禁用。所有没有聚焦的项目都标记为 注意力不集中,应该调暗。
因此,变暗的逻辑是:
NOT IsFocused AND (IsDefocused OR NOT Enabled)
为了实现这个逻辑,我制作了一个通用的 IMultiValueConverter来匹配我的逻辑
IMultiValueConverter
// '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); } ... }
在 XAML 中,我在 <Style><Style.Triggers>资源的 MultiDataTrigger中使用了这一点
<Style><Style.Triggers>
MultiDataTrigger
<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>
为了完整起见,我的转换器是在 ResourceDictionary中定义的
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>
这个答案只适用于 < br > 动画 $(PROCESSOR _ ARCHITEW6432) $(PROCESSOR _ IDENTIFIER) 如果你想实现 AND 逻辑,你应该使用 MultiTrigger,这里有一个例子: < br > $(处理器 _ 级别) $(PROCESSOR _ REVISION) 假设我们想要执行一些操作,如果属性 Text = “”(空字符串) 还有 IsKeyboardFocus = “ False”,那么您的代码应该如下所示:
<MultiTrigger> <MultiTrigger.Conditions> <Condition Property="Text" Value="" /> <Condition Property="IsKeyboardFocused" Value="False" /> </MultiTrigger.Conditions> <MultiTrigger.EnterActions> <!-- Your actions here --> </MultiTrigger.EnterActions> </MultiTrigger>
如果您想实现 OR 逻辑,有几种方法,这取决于您尝试做什么: < br >
第一个选项是使用多个触发器。 $(ProgramW6432) $(ProjectDir) 那么,假设您想要执行某些操作,如果 Text = “”或者 IsKeyboardFocus = “ False”, $(ProjectExt) 那么您的代码应该是这样的:
<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>
$(ProjectFileName) $(ProjectGuid) 但这里的问题是,如果我想做一些事情,如果文本不为空 或者 IsKeyboard = “ True”,我该怎么做?这可以通过第二种方法实现: $(ProjectName) 回想一下德摩根定律,它说! (! x & & ! y) = x | | y。 $(ProjectPath) $(PSExectionPolicyPreferences) 因此,我们将使用它来解决前面的问题,方法是编写一个当 Text = “”和 IsKeyboard = “ True”时触发的多触发器,我们将在 撤离行动中执行操作,如下所示: < br >
<MultiTrigger> <MultiTrigger.Conditions> <Condition Property="Text" Value="" /> <Condition Property="IsKeyboardFocused" Value="False" /> </MultiTrigger.Conditions> <MultiTrigger.ExitActions> <!-- Do something here --> </MultiTrigger.ExitActions> </MultiTrigger>