触发器与依赖关系 属性 优先级
Trigger vs. Dependency Property precendence
我对依赖项 属性 值的优先级有疑问。
我的 .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>
在我的代码隐藏中,我创建了依赖项 属性 '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-属性 后,如何让触发器再次工作?
您的代码更改实际上被视为本地更改。从您在 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.
我突出显示了相关部分,指出像您那样调用 SetValue
(通过您的 BG
CLR 属性)将导致 Local 改变。由于 Local 更改的优先级高于 Trigger
,它否决了 Trigger
值。
而不是
BG = Brushes.Green;
设置一个局部值比触发器更高的优先级,你可以这样写
SetCurrentValue(BGProperty, Brushes.Green);
来自MSDN:
... The SetCurrentValue method changes the effective value of the
property, but existing triggers, data bindings, and styles will
continue to work.
我对依赖项 属性 值的优先级有疑问。 我的 .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>
在我的代码隐藏中,我创建了依赖项 属性 '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-属性 后,如何让触发器再次工作?
您的代码更改实际上被视为本地更改。从您在 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.
我突出显示了相关部分,指出像您那样调用 SetValue
(通过您的 BG
CLR 属性)将导致 Local 改变。由于 Local 更改的优先级高于 Trigger
,它否决了 Trigger
值。
而不是
BG = Brushes.Green;
设置一个局部值比触发器更高的优先级,你可以这样写
SetCurrentValue(BGProperty, Brushes.Green);
来自MSDN:
... The SetCurrentValue method changes the effective value of the property, but existing triggers, data bindings, and styles will continue to work.