Trigger vs. Dependency Property precendence

133 views Asked by At

I've got a question about the precendence of dependency property value. My .xaml looks lik the following:

<Window x:Class="WpfTests.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local ="clr-namespace:WpfTests"
    Title="MainWindow" Height="350" Width="525">
<Window.Style>
    <Style>
        <!--<Setter Property="Canvas.Background" Value="Gray"/>-->
        <Style.Triggers>
            <Trigger Property="local:MainWindow.IsMouseOver" Value="True">
                <!--<Setter Property="local:LeistenPfeil.Symbolfarbe" Value="Red"/>-->
                <Setter Property="local:MainWindow.Cursor" Value="Hand" />
                <Setter Property="local:MainWindow.BG" Value="Blue"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Style>

<Grid Background="{Binding BG,Mode=TwoWay}">
    <Button Content="ChangeBG" HorizontalAlignment="Center" VerticalAlignment="Center" Click="OnClick"/>
</Grid>

In my Codebehind I created the dependency property 'BG' like:

public partial class MainWindow : Window
{
    public Brush BG
    {
        get { return (Brush)GetValue(BGProperty); }
        set { SetValue(BGProperty, value); }
    }

    // Using a DependencyProperty as the backing store for BG.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty BGProperty =
        DependencyProperty.Register("BG", typeof(Brush), typeof(MainWindow), new PropertyMetadata(Brushes.Black));


    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    private void OnClick(object sender, RoutedEventArgs e)
    {
        BG = Brushes.Green;
    }
}

So, on startup the background is set to black (Default of DP). When mouse is over the background changes to blue. When it comes to a change of the BG-property in my codebehind, the trigger does work, but its influence to the grid-background vanished. I've already read this article on MSDN: https://msdn.microsoft.com/en-us/library/ms743230%28v=vs.110%29.aspx

The problem in my understanding is: Why does the trigger work while the BG-property has its default value and doesn't when it changes in code behind? => The highest precendence of the background is the local background-binding of the grid, so why does the trigger work at all?

How can I get the trigger working again, after a change of BG-property in code behind?

2

There are 2 answers

3
Sheridan On BEST ANSWER

Your code change is actually deemed to be a Local change. From your linked page on MSDN:

Local value. A local value might be set through the convenience of the "wrapper" property, which also equates to setting as an attribute or property element in XAML, or by a call to the SetValue API using a property of a specific instance. If you set a local value by using a binding or a resource, these each act in the precedence as if a direct value was set.

I have highlighted the relevant part that states that calling SetValue as you did (via your BG CLR property) will result in a Local change. As a Local change has higher precedence than a Trigger, it overrules the Trigger value.

1
Clemens On

Instead of

BG = Brushes.Green;

which sets a local value with higher precedence than a Trigger, you could write

SetCurrentValue(BGProperty, Brushes.Green);

From MSDN:

... The SetCurrentValue method changes the effective value of the property, but existing triggers, data bindings, and styles will continue to work.