我有一个简单的按钮触发器:
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#3E6DB6"/>
</Trigger>
</Style.Triggers>
这很好用,直到我在代码隐藏中设置按钮的背景:
neighborButton.Background = notClickedButtonBackground;
此neighborButton.Triggers
集合变为空并且功能丢失后。
为什么会出现这种行为?
答案 0 :(得分:0)
依赖属性比常规C#属性复杂得多。您正在做的是设置"Local value", which will override Style trigger setters.如果您在XAML中的Background
元素的属性中设置Button
画笔,您将获得相同的效果(但是您和#39; d将它作为控件的初始状态,并且你在这里问为什么你的触发器根本不起作用。答案是将所有代码都放在后面,或添加属性以暴露逻辑并在触发器中执行,但不要尝试将两者混合使用。当你对抗框架时,框架通常会笑到最后。我对框架的正面攻击充其量只有Pyrrhic victories和more often debacles。
我不建议在代码背后执行此操作,但如果您已经投入了大量时间,那么您可以坚持使用该项目。但是,这意味着您丢失了鼠标悬停颜色。你可以尝试在代码背后做到这一点。
值得一看DependencyObject.GetValue()
和DependencyObject.ReadLocalValue()
的MSDN页面,我将在下面使用这些页面。
我无法通过消失的触发器重现您的行为。即使在事件处理程序中设置背景后,我仍然有一个触发器。它没有任何效果。
XAML:
<Button
Click="Button_Click"
Content="Click Me"
>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#3E6DB6" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
C#:
private void Button_Click(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
var triggers = btn.Style.Triggers;
// GetValue returns the "effective value": Maybe local, maybe not;
// whatever it is, it's the value that will be used.
var background = btn.GetValue(Button.BackgroundProperty);
// If there's a local value, it overrides whatever else has been set.
// Note that a value set by a template trigger on a property of an
// element within the template is a local value.
var localbackground = btn.ReadLocalValue(Button.BackgroundProperty);
// Right now,
// background == #FF3E6DB6
// localbackground == DependencyProperty.UnsetValue
btn.Background = new SolidColorBrush(Colors.YellowGreen);
background = btn.GetValue(Button.BackgroundProperty);
localbackground = btn.ReadLocalValue(Button.BackgroundProperty);
// Now they're both #FF9ACD32, which is YellowGreen
// triggers.Count == 1
btn.Content = $"Trigger count: {triggers?.Count}";
}