设置控件后台后,Wpf控件触发器集合清除

时间:2016-04-27 13:04:16

标签: wpf button triggers code-behind

我有一个简单的按钮触发器:

    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="#3E6DB6"/>
        </Trigger>
    </Style.Triggers>

这很好用,直到我在代码隐藏中设置按钮的背景:

neighborButton.Background = notClickedButtonBackground;

neighborButton.Triggers集合变为空并且功能丢失后。 为什么会出现这种行为?

1 个答案:

答案 0 :(得分:0)

依赖属性比常规C#属性复杂得多。您正在做的是设置"Local value", which will override Style trigger setters.如果您在XAML中的Background元素的属性中设置Button画笔,您将获得相同的效果(但是您和#39; d将它作为控件的初始状态,并且你在这里问为什么你的触发器根本不起作用。答案是将所有代码都放在后面,或添加属性以暴露逻辑并在触发器中执行,但不要尝试将两者混合使用。当你对抗框架时,框架通常会笑到最后。我对框架的正面攻击充其量只有Pyrrhic victoriesmore 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}";
}