【问题标题】:Trigger vs. Dependency Property precendence触发器与依赖属性优先级
【发布时间】:2015-08-24 06:16:31
【问题描述】:

我有一个关于依赖属性值优先级的问题。 我的 .xaml 如下所示:

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

在我的 Codebehind 中,我创建了依赖属性“BG”,例如:

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

因此,在启动时背景设置为黑色(DP 的默认值)。当鼠标悬停在背景上时变为蓝色。当我的代码隐藏中的 BG 属性发生变化时,触发器确实有效,但它对网格背景的影响消失了。 我已经在 MSDN 上阅读了这篇文章: https://msdn.microsoft.com/en-us/library/ms743230%28v=vs.110%29.aspx

我理解的问题是:为什么触发器在 BG 属性具有其默认值时起作用,而当它在后面的代码中发生变化时却不起作用? => 背景的最高优先级是网格的本地背景绑定,那么为什么触发器会起作用呢?

如何在后台代码中更改 BG 属性后让触发器再次工作?

【问题讨论】:

  • 绑定Background="{Binding BG,Mode=TwoWay}"没有设置BG属性的值。这里 BG 是绑定的源,而不是目标。

标签: c# .net wpf triggers dependency-properties


【解决方案1】:

您的代码更改实际上被视为本地更改。从您在 MSDN 上的链接页面:

本地值。可以通过“包装器”属性的便利设置本地值,这也等同于在 XAML 中设置为属性或属性元素,或通过使用特定实例的属性调用 SetValue API强>。如果您使用绑定或资源设置本地值,则它们各自的优先级就像设置了直接值一样。

我已经强调了相关部分,指出像您所做的那样调用SetValue(通过您的BG CLR 属性)将导致本地更改。由于本地更改的优先级高于Trigger,它会否决Trigger 值。

【讨论】:

  • 感谢您的快速回复:),我已经阅读了这个,但也许我没有明白重点...在 PropertyMetada 中设置依赖属性的默认值或多或少调用属性的 SetValue 不是吗?如果是这种情况,那么触发器将从一开始就具有较低的优先级。我想知道将元数据设置为黑色是否与调用 SetValue 不同?
  • 再看一遍...默认属性值在列表的最后:依赖属性元数据的默认值。因此,其他一切都可以覆盖它。
  • 哦,我必须把这个读一遍,它清楚地站在那里......非常感谢!是否有解决方法,以便我可以再次重新激活触发器?
【解决方案2】:

代替

BG = Brushes.Green;

它设置了一个比触发器优先级更高的本地值,你可以这样写

SetCurrentValue(BGProperty, Brushes.Green);

来自MSDN

... SetCurrentValue 方法改变了有效值 属性,但现有的触发器、数据绑定和样式将 继续工作。

【讨论】:

  • 感谢您的回复:),我的意图是更改属性的来源。当我按下按钮时,如果鼠标离开,我希望网格背景为绿色,如果鼠标结束,则为蓝色。所以我可以说我可以在后面的代码中更改我的源代码并松开我的触发器,或者我可以使用 SetCurrentValue() 更改属性但不能长期将背景更改为绿色。对吗?
猜你喜欢
  • 1970-01-01
  • 2011-05-13
  • 1970-01-01
  • 1970-01-01
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多