【问题标题】:Trigger won't change Background触发器不会改变背景
【发布时间】:2013-11-04 14:51:08
【问题描述】:

我正在尝试为按钮创建一个模板,以防止控件在禁用时变灰,它工作得很好,但由于某种原因,一旦我为其设置颜色,它就不会改变背景按钮属性。

这是我制作的按钮:

    <Style TargetType="Button" x:Key="TestButton">
        <Setter Property="SnapsToDevicePixels" Value="true" />
        <Setter Property="OverridesDefaultStyle" Value="true" />
        <Setter Property="MinHeight" Value="29px" />
        <Setter Property="MinWidth"  Value="103px" />
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="Background" Value="#EEEEEE"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Border TextBlock.Foreground="{TemplateBinding Foreground}" x:Name="Border">
                        <Border.Background>
                            <SolidColorBrush  Color="{TemplateBinding Background}" />
                        </Border.Background>
                        <Border.BorderBrush>
                            <SolidColorBrush  Color="Black" />
                        </Border.BorderBrush>
                        <Border.BorderThickness>
                            <Thickness Top="0.75" Bottom="0.75" Right="0.75" Left="0.75"/>
                        </Border.BorderThickness>
                        <Border.CornerRadius>
                            <CornerRadius TopLeft="3" TopRight="3" BottomLeft="3" BottomRight="3"/>
                        </Border.CornerRadius>
                        <ContentPresenter Margin="2"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        RecognizesAccessKey="True" />
                    </Border>
                    <!--Triggers-->
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="#E1F3FD" />
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="Background" Value="#C4E9FF" />
                            <Setter Property="Effect">
                                <Setter.Value>
                                    <DropShadowEffect Color="Black" Direction="500" ShadowDepth="1" BlurRadius="5" Opacity="0.5" />
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Background}"/>
                            <Setter Property="Opacity" Value="0.5" />
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="True"  >
                            <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Background}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

当我调用它时,我给出了两个不同的结果,一个有效的结果如下:

<Button Style="{DynamicResource ResourceKey=TestButton}" Content="Button" Height="66" Name="button1" Width="149" Click="button1_Click" />

但是当我向它添加背景时,由于某种原因它会停止更改背景:

<Button Style="{DynamicResource ResourceKey=TestButton}" Background="Orange" Content="Button" Height="66" Name="button1" Width="149" Click="button1_Click" />

【问题讨论】:

  • Background="Orange" 添加到样式中,您应该一切顺利。
  • 怎么样?如果我将它添加到按钮样式中它不起作用,并且我不想将它添加到我的模板中,因为它应该与所有颜色兼容,因为用户要定义它。我的意思是,如果用户在运行时更改颜色,整个模板应该仍然可以工作。

标签: wpf xaml


【解决方案1】:

它不会改变颜色,因为你用你在 MainWindow.xaml 中定义的颜色“覆盖”了颜色。

它称为依赖属性值优先级。

要了解更多信息,请查看以下内容:

http://msdn.microsoft.com/en-us/library/ms743230.aspx

在您的情况下发生的情况是您在样式和触发器中定义了背景,但随后您在 MainWindow 中设置了值。 MainWindow 中设置的值被认为是本地值,而 style 中设置的值是“样式 - 值”。

如果你看一下我给你的链接,你会发现本地价值在“风格 - 价值”之前。

局部值非常强大。

这就是为什么您的 Button 即使在禁用时也始终为橙色的原因。当您的触发器触发时,属性系统将尝试为背景找到一个值,并且它总是会找到本地的值,因为这是具有最高优先级的值。

为了使其正常工作,在设置 Button 的背景值时,您必须使用 SetCurrentValue 而不是 SetValue。 (意味着您将不得不覆盖 Buttons 代码)

看看这个:

http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.setcurrentvalue.aspx

此方法由以编程方式设置其自身属性之一的值的组件使用,而不会禁用应用程序对属性的声明使用。 SetCurrentValue 方法更改属性的有效值,但现有的触发器、数据绑定和样式将继续工作。

编辑:

了解依赖属性值优先级和命中测试的示例。

<Window.Resources>
    <Style TargetType="{x:Type Grid}">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="Yellow" />
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style TargetType="{x:Type TextBlock}">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="Red" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <TextBlock Height="20" Margin="40" Text="asdfasdfa" VerticalAlignment="Bottom"/>
    <Rectangle  Height="100" VerticalAlignment="Bottom" >
        <Rectangle.Fill>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Offset="0"/>
                <GradientStop Color="White" Offset="1"/>
            </LinearGradientBrush>
        </Rectangle.Fill>
    </Rectangle>
</Grid>

【讨论】:

  • 那么没有办法只使用模板来改变背景吗?太糟糕了,我非常讨厌禁用它会变成灰色,所以我认为制作自己的按钮可以解决它......
  • 您好,您的问题解决了吗?是的,有一种方法,但要么使用 SetCurrentValue,要么通过一些技巧。
  • 你介意举个例子吗?到目前为止,我已经阅读了您提供的内容,但未能成功。
  • 我给你发了一个例子。看看我的编辑。如果您了解这一点,您将知道如何解决您的问题。如有任何关于我将给您的示例的问题,请随时提出。
  • 好吧,我理解您的示例并尝试了它,但同样的问题仍然存在,因为即使用户定义了背景,我也希望该样式能够正常工作。换句话说,在您的代码中,当我定义背景时,它不会改变触发器由于优先列表而触发的颜色。
【解决方案2】:

如果您查看DependecyProperty value precedence order,您会发现在控件上显式设置值(视为本地值)将覆盖触发器设置的任何值。

【讨论】:

    【解决方案3】:

    请注意:Background 属性的类型是 Brush,所以你应该写

    <Border Background="{TemplateBinding Background}" ...>
        ...
    </Border>
    

    而不是

    <Border ...>
        <Border.Background>
            <SolidColorBrush Color="{TemplateBinding Background}" />
        </Border.Background>
        ...
    </Border>
    

    【讨论】:

    • 不知道为什么我这样做,改变了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 2014-04-21
    • 1970-01-01
    相关资源
    最近更新 更多