【问题标题】:Wpf control triggers collection clears after setting control backgroundWpf控件设置控件背景后触发集合清除
【发布时间】:2016-04-27 13:04:15
【问题描述】:

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

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

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

neighborButton.Background = notClickedButtonBackground;

在此neighborButton.Triggers 集合变为空并且功能丢失之后。 为什么会导致这种行为?

【问题讨论】:

  • "Local values" override Style trigger setters。如果您在 XAML 中 Button 元素的属性中设置背景颜色,您将获得相同的效果。答案是使用后面的代码,或者添加属性来公开逻辑并在触发器中执行,但不要尝试将两者混合。当你与框架作斗争时,框架通常会笑到最后。
  • 谢谢 Ed,我不清楚。

标签: wpf button triggers code-behind


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多