为什么为控件指定背景颜色会覆盖样式触发器?

时间:2014-07-15 14:45:24

标签: wpf

我有一个带标签的简单WPF窗口。当鼠标悬停在标签上时,窗口中有一种默认样式可将标签背景更改为红色。很简单。

这是有效的,只要我不在任何地方设置/修改标签颜色。

  • 如果我在后面的代码中设置标签背景(通过下面代码中的'设置标签背景'按钮),样式触发器将停止工作
  • 如果我在XAML中设置标签背景(未显示,但是很容易编辑),则样式不起作用。
  • 如果在后面的代码中设置标签颜色后,我尝试将背景恢复为原样(无论是空还是透明),触发器从工作状态变为无效状态。

我不明白为什么设置背景似乎会覆盖这种风格。

我更喜欢这样做是为了让风格保持活跃状态​​,无论我为标签设置了什么背景 - 如果我将鼠标移动,它应该将颜色更改为红色,无论我是否'将它设置为蓝色或其他任何东西。如果我必须在后面的代码中创建触发器,我很好。

相反,它似乎只是通过为标签指定背景颜色,我覆盖了样式。

这是XAML:                                                                                                                     

    <Grid Background="Black">   
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <Button Grid.Column="0" Grid.Row="0" Margin="10,10,10,10" Height="75" Click="Button_Set_Click">Set Label Background</Button>
    <Button Grid.Column="0" Grid.Row="1" Margin="10,10,10,10" Height="75" Click="Button_Clear_Click">Clear Label Background</Button>
    <Label Name="TestLabel" Grid.Row="2"  Margin="10,10,10,10" BorderBrush="Gray" BorderThickness="5"></Label>
    </Grid>

这是背后的代码:

public partial class WpfProblems : Window
{
    public WpfProblems()
    {
        InitializeComponent();
    }

    private void Button_Clear_Click(object sender, RoutedEventArgs e)
    {
        // revert the label background color - I've tried setting to null, transparent also
        // but the trigger never comes back. 
        TestLabel.Background = (Brush)new BrushConverter().ConvertFrom("#00FFFFFF");            
    }

    private void Button_Set_Click(object sender, RoutedEventArgs e)
    {
        // Set the label background color
        TestLabel.Background = Brushes.Blue;
    }
}

2 个答案:

答案 0 :(得分:3)

通过为Label指定颜色,您将覆盖其Color属性(之前保存绑定)。所以最后你通过直接在后面的代码或xaml中分配颜色来打破绑定。

要修复问题,您必须在标签样式中指定默认颜色,以便在触发条件完成后保留颜色。

让我们说你的风格如下所示。请注意我如何设置触发器部分上方标签的默认颜色。

<Style TargetType="{x:Type Label}">
<Setter Property="Background" Value="Blue"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="Red/>
</Trigger>
</Style.Triggers>
</Style>

编辑 -

由于您使用的是Code Behind文件,我认为您可以使用DependencyProperty来控制标签的颜色。我在测试应用程序上尝试了这个并且它有效。

创建一个dependencyProperty,如下所示。请注意,默认颜色为测试应用程序中的蓝色。

public Brush BackgroundColor
        {
            get { return (Brush)GetValue(BackgroundColorProperty); }
            set { SetValue(BackgroundColorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BackgroundColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BackgroundColorProperty =
            DependencyProperty.Register("BackgroundColor", typeof(Brush), typeof(MainWindow), new PropertyMetadata(Brushes.Blue));

现在您的按钮点击事件将变为

private void Button_Click(object sender, RoutedEventArgs e)
        {
            BackgroundColor = Brushes.Yellow;
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            BackgroundColor = Brushes.Blue;
        }

在主窗口(或您的用户控件)中,我为标签

定义了以下样式
<Window.Resources>
        <Style TargetType="{x:Type Label}">
            <Setter Property="Background" Value="{Binding BackgroundColor}"/>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="true">
                    <Setter Property="Background" Value="Red"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>



<Grid Background="Black">
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <Button Grid.Column="0" Grid.Row="0" Margin="10,10,10,10" Height="75" Click="Button_Click">Set Label Background</Button>
            <Button Grid.Column="0" Grid.Row="1" Margin="10,10,10,10" Height="75" Click="Button_Click_1">Clear Label Background</Button>
            <Label Name="TestLabel"  Grid.Row="2"  Margin="10,10,10,10" BorderBrush="Gray" BorderThickness="5"></Label>
        </Grid>

我正在使用您发布的相同网格

确保在后面的代码中正确设置控件的datacontext以使其工作。现在,即使您单击任何按钮,原始样式也会保留。

让我知道这是否有效。

答案 1 :(得分:1)

DependencyProperty可以从许多不同的来源设置。例如,可以在Style s,Animation s,Trigger s等中设置它们。因此,Microsoft确定其中一些更新源比其他更新源更重要应该优先于其他人。

例如,Setter中的Trigger应优先于普通Style Setter,否则,Trigger将无法正常工作。< / p>

  

我更喜欢这样做是为了让风格保持活跃状态​​,无论我为标签设置了什么背景

显然,根据您设置Background的方式,这可能不起作用...代码中的简单属性设置将始终覆盖Style中设置的属性。

要了解详情,请阅读MSDN上的Dependency Property Value Precedence页面。