WPF样式触发器中的Setter与本地值结合使用的行为不一致

时间:2016-08-24 11:55:01

标签: c# .net wpf wpf-controls wpf-style

我正在为我的WPF应用程序使用自定义TextBox控件,该应用程序在Generics.xaml文件中设置了默认样式。我在文件中设置的模板包括以下Setter和Triggers:

<Setter Property="Background" Value="Blue" />

<Trigger Property="IsFocused" Value="True">
    <Setter Property="Background" Value="Yellow"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="BorderBrush" Value="Black"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
    <Condition Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}}" Value="True" />
    <Condition Binding="{Binding Path=IsFocused, RelativeSource={RelativeSource Self}}" Value="False" />
    <Condition Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource Self}}" Value="False" />
    <Condition Binding="{Binding Path=Text, RelativeSource={RelativeSource Self}, Converter={StaticResource IsEmptyStringConverter}}" Value="False" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
    <Setter Property="Background" Value="Green" TargetName="Border" />
    <Setter Property="Foreground" Value="White"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>

如果我没有为Background属性设置Local Value,则此代码按预期工作。聚焦时,我的背景变为黄色,当没有聚焦且没有验证错误时,它变为绿色。

但是,如果我为Background属性设置了Local Value,就像在下面的代码片段中一样,当触发其中一个触发器时,Background行为很奇怪。

<custom:TextBox Background="Orange" />

  • 触发IsFocued触发器后,背景将保持橙色。我假设这是由于WPF的Dependency Property Setting Precedence,它支持本地值而不是样式触发器中设置的值。是的,随着BorderBrush和Foreground的改变,触发器肯定会被触发。
  • 当触发第二个触发器(用于验证的MultiDataTrigger)时,背景将变为绿色。忽略本地值。

据我所知,这是不一致的。为什么第一个Trigger使用我的Local Value而第二个触发它的Background Setter?这两个触发器之间是否有任何不同的优先级?

1 个答案:

答案 0 :(得分:0)

样式触发器模板触发器无法更改本地值设置的值 但他们可以使用模板化模板

更改该控件子项的继承属性

示例:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication2"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Background" Value="Red"></Setter>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="Green"></Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

    <Grid>
        <Button Width="100" Height="100" Background="Pink"></Button>
    </Grid>
</Window>

在示例中,按钮Backgound属性将保持粉红色(本地值),您可以看到使用Snoop

但是如果将鼠标悬停在按钮上,您将看到背景正在发生变化,因为按钮(边框)的子项由其父TemplatedParent和TemplatedParent.Trigger更改。再次使用Snoop查看值源