在 WPF 样式中触发多个条件的正确方法是什么

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12159973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:30:00  来源:igfitidea点击:

What's the right way to trigger on multiple conditions in a WPF Style

wpfxamltriggersstylesmultidatatrigger

提问by Tony Vitabile

My WPF application has a DataGridcontrol in it. I have a default custom style for the DataGridRowclass which works well. However, for this one particular DataGridon this one particular screen, I need a different custom style.

我的 WPF 应用程序中有一个DataGrid控件。我有一个默认的自定义样式DataGridRow,效果很好。但是,对于这个DataGrid特定屏幕上的这个特定样式,我需要一种不同的自定义样式。

The Items in each row have a boolproperty that, when set, I want to display that row with a different foreground and background color. 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.

每行中的项目都有一个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.

Here's what I've tried:

这是我尝试过的:

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

This gives me a "Binding must be non-null" error, which I think is happening because there is no Bindingproperty on the first condition in the MultiDataTrigger.

这给了我一个“绑定必须为非空”错误,我认为这是因为BindingMultiDataTrigger 中的第一个条件没有属性。

What is the correct way to write this in XAML?

在 XAML 中编写它的正确方法是什么?

EDIT:

编辑:

After trying nemesv's & Rachel's answer, the code now compiles and runs. However, the colors I've chosen for the IsSelected = true and IsInLiveMode = true case are not showing up. Here's what I have now:

在尝试了 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>

Any ideas on why the case in question isn't working?

关于为什么有问题的案例不起作用的任何想法?

回答by nemesv

Your assumptution is correct regarding the missing binding.

您对缺少绑定的假设是正确的。

From MSDN MultiDataTrigger.Conditions:

从 MSDN MultiDataTrigger.Conditions

For a MultiDataTrigger, each condition in the collection must set both the Binding and Valueproperties.

对于 MultiDataTrigger,集合中的每个条件都必须设置 Binding 和 Value属性。

You can solve this using RelativeSource Selfto refer yourself in the binding:

您可以使用RelativeSource Self在绑定中引用自己来解决此问题:

<MultiDataTrigger.Conditions>
    <Condition Binding="{Binding RelativeSource={RelativeSource Self},
         Path=IsSelected}" Value="True" />
    <Condition Binding="{Binding Path=IsInLiveMode}" Value="True" />
</MultiDataTrigger.Conditions>

回答by Rachel

You're using a MultiDataTrigger, which is still a DataTriggerand expects a binding

您正在使用 a MultiDataTrigger,它仍然是 aDataTrigger并且需要绑定

Switch Property="IsSelected"in your Conditionto

开关Property="IsSelected"在你Condition

<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" 
           Value="True" />