在 WPF 样式中触发多个条件的正确方法是啥
Posted
技术标签:
【中文标题】在 WPF 样式中触发多个条件的正确方法是啥【英文标题】:What's the right way to trigger on multiple conditions in a WPF Style在 WPF 样式中触发多个条件的正确方法是什么 【发布时间】:2012-08-23 00:04:30 【问题描述】:我的 WPF 应用程序中有一个 DataGrid
控件。我有一个适用于 DataGridRow
类的默认自定义样式,效果很好。但是,对于这一特定屏幕上的这一特定DataGrid
,我需要一种不同的自定义样式。
每一行中的项目都有一个bool
属性,当设置该属性时,我想用不同的前景色和背景色显示该行。 However, when the row is selected AND when that property is set, I want a different foreground and background color to show that it's selected AND the property is set to true.
这是我尝试过的:
<Style TargetType="DataGridRow" x:Key="CameraStyle">
<Setter Property="Foreground" Value="DynamicResource TextForeground" />
<Setter Property="Background" Value="DynamicResource DataBackground" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Property="IsSelected" Value="False" />
<Condition Binding="Binding Path=IsInLiveMode" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Foreground" Value="Red" />
<Setter Property="Background" Value="Yellow" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Property="IsSelected" Value="True" />
<Condition Binding="Binding Path=IsInLiveMode" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="DarkOrange" />
<Setter Property="BorderBrush" Value="DynamicResource DataBorder" />
<Setter Property="Foreground" Value="DarkRed" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
这给了我一个“绑定必须为非空”错误,我认为这是因为 MultiDataTrigger 中的第一个条件没有 Binding
属性。
在 XAML 中编写此代码的正确方法是什么?
编辑:
在尝试了 nemesv 和 Rachel 的回答后,代码现在可以编译并运行。但是,我为 IsSelected = true 和 IsInLiveMode = true 案例选择的颜色没有显示出来。这是我现在拥有的:
<Style TargetType="DataGridRow" x:Key="CameraStyle">
<Setter Property="Background" Value="DynamicResource DataBackground" />
<Setter Property="Foreground" Value="DynamicResource TextForeground" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="Binding Path=IsSelected, RelativeSource=RelativeSource Self" Value="False" />
<Condition Binding="Binding Path=IsInLiveMode" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="Yellow" />
<Setter Property="Foreground" Value="Red" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="Binding Path=IsSelected, RelativeSource=RelativeSource Self" Value="True" />
<Condition Binding="Binding Path=IsInLiveMode" Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="DynamicResource DataBackgroundSelected" />
<Setter Property="BorderBrush" Value="DynamicResource DataBorder" />
<Setter Property="Foreground" Value="DynamicResource DataForegroundSelected" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="Binding Path=IsSelected, RelativeSource=RelativeSource Self" Value="True" />
<Condition Binding="Binding Path=IsInLiveMode" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="DarkOrange" />
<Setter Property="BorderBrush" Value="DynamicResource DataBorder" />
<Setter Property="Foreground" Value="DarkRed" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
关于为什么有问题的案例不起作用的任何想法?
【问题讨论】:
其他两种情况,尤其是IsInLiveMode=true
和IsSelected=false
的情况是否正常工作?
我对您的触发器进行了快速测试,它们工作正常,但是背景颜色并不总是被DataGridCell
继承。更改它的最简单方法是对 DataGridCell
使用隐式样式,将 Background
设置为 Transparent
雷切尔:谢谢!这是有道理的。
【参考方案1】:
您关于缺少绑定的假设是正确的。
来自 MSDN MultiDataTrigger.Conditions:
对于 MultiDataTrigger,集合中的每个条件必须同时设置 Binding 和 Value 属性。
您可以使用RelativeSource Self 在绑定中引用自己来解决此问题:
<MultiDataTrigger.Conditions>
<Condition Binding="Binding RelativeSource=RelativeSource Self,
Path=IsSelected" Value="True" />
<Condition Binding="Binding Path=IsInLiveMode" Value="True" />
</MultiDataTrigger.Conditions>
【讨论】:
nemesv:谢谢,至少不会引发任何错误。还有一个问题。请查看我对原始问题的修改。【参考方案2】:您正在使用 MultiDataTrigger
,它仍然是 DataTrigger
并且需要绑定
将Condition
中的Property="IsSelected"
切换为
<Condition Binding="Binding IsSelected, RelativeSource=RelativeSource Self"
Value="True" />
【讨论】:
Rachel:我希望我能把你和@nemesv 的答案作为正确答案,因为你们都是对的。但 nemesv 确实先回答,所以他得到了复选标记。 @TonyVitabile 没关系,我认为无论如何他的答案更好,因为 MSDN 链接,并且已经给了他一个 +1 :)以上是关于在 WPF 样式中触发多个条件的正确方法是啥的主要内容,如果未能解决你的问题,请参考以下文章
WPF MVVM 从 ViewModel 触发事件的正确方法
WPF 解决多个TreeViewItem同时触发某事件的简单方法
WPF 解决多个TreeViewItem同时触发某事件的简单方法