【问题标题】:Background does not change of button C# WPF背景不改变按钮C# WPF
【发布时间】:2015-02-05 14:44:55
【问题描述】:

我正在尝试更改鼠标悬停时的样式。

我的代码是:

<Button Name="register" Content="Register" Margin="15,410,20,0" Padding="6" FontSize="18" VerticalAlignment="Top" Background="#FF0090D6" BorderBrush="#FF0090D6" Foreground="White">
                    <Button.Style>
                        <Style TargetType="Button">
                            <Style.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Background" Value="Red"></Setter>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </Button.Style>
                </Button>

但背景是相同的默认设置。但是当我将属性更改为BorderThickness 时,它就可以工作了。

我做错了什么?

【问题讨论】:

  • 如果你为颜色设置一个 RGBA 值是否有效?
  • @Stilgar 如何设置 rgba?属性窗口确实显示了我输入的颜色

标签: c# wpf


【解决方案1】:

在按钮的默认模板中,ControlTemplate 中有一个触发器,它将按钮的背景设置为#FFBEE6FD,并且由于与样式触发器相比,控件模板触发器具有higher precedence,这就是为什么您的触发器永远无法工作的原因。

为此,您必须覆盖按钮的默认模板并从中删除该触发器,以便应用您的样式触发器。

这是带有注释掉特定触发器的默认模板。如果您还想覆盖 BorderBrush,也请从模板中删除它。

<ControlTemplate x:Key="DefaultTemplateOfButton" TargetType="ButtonBase">
    <Border BorderThickness="{TemplateBinding Border.BorderThickness}"
                BorderBrush="{TemplateBinding Border.BorderBrush}"
                Background="{TemplateBinding Panel.Background}"
                Name="border"
                SnapsToDevicePixels="True">
        <ContentPresenter RecognizesAccessKey="True"
                                Content="{TemplateBinding ContentControl.Content}"
                                ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                                ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
                                Name="contentPresenter"
                                Margin="{TemplateBinding Control.Padding}"
                                HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
                                SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
                                Focusable="False" />
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="Button.IsDefaulted" Value="True">
            <Setter Property="Border.BorderBrush" TargetName="border">
                <Setter.Value>
                    <DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" />
                </Setter.Value>
            </Setter>
        </Trigger>
        <Trigger Property="UIElement.IsMouseOver" Value="True">
            <!--<Setter Property="Panel.Background" TargetName="border">
                <Setter.Value>
                    <SolidColorBrush>#FFBEE6FD</SolidColorBrush>
                </Setter.Value>
            </Setter>-->
            <Setter Property="Border.BorderBrush" TargetName="border">
                <Setter.Value>
                    <SolidColorBrush>#FF3C7FB1</SolidColorBrush>
                </Setter.Value>
            </Setter>
        </Trigger>
        <Trigger Property="ButtonBase.IsPressed" Value="True">
            <Setter Property="Panel.Background" TargetName="border">
                <Setter.Value>
                    <SolidColorBrush>#FFC4E5F6</SolidColorBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Border.BorderBrush" TargetName="border">
                <Setter.Value>
                    <SolidColorBrush>#FF2C628B</SolidColorBrush>
                </Setter.Value>
            </Setter>
        </Trigger>
        <Trigger Property="ToggleButton.IsChecked" Value="True">
            <Setter Property="Panel.Background" TargetName="border">
                <Setter.Value>
                    <SolidColorBrush>#FFBCDDEE</SolidColorBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Border.BorderBrush" TargetName="border">
                <Setter.Value>
                    <SolidColorBrush>#FF245A83</SolidColorBrush>
                </Setter.Value>
            </Setter>
        </Trigger>
        <Trigger Property="UIElement.IsEnabled" Value="False">
            <Setter Property="Panel.Background" TargetName="border">
                <Setter.Value>
                    <SolidColorBrush>#FFF4F4F4</SolidColorBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Border.BorderBrush" TargetName="border">
                <Setter.Value>
                    <SolidColorBrush>#FFADB2B5</SolidColorBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="TextElement.Foreground" TargetName="contentPresenter">
                <Setter.Value>
                    <SolidColorBrush>#FF838383</SolidColorBrush>
                </Setter.Value>
            </Setter>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

如何将控件模板设置为按钮?

在父面板或 UserControl 的资源部分下的某处定义模板,并且可以通过 StaticResource 应用:

<Grid>
   <Grid.Resources>
      <ControlTemplate x:Key="MyTemplate"
                       TargetType="ButtonBase">
       .......
   </Grid.Resources>
   <Button Name="register" Template="{StaticResource MyTemplate}"...>
</Grid>

【讨论】:

  • 如何将控件模板设置为按钮
  • 编辑了一个答案。检查一下。
  • 不知道模板属性
  • 我认为一个更简单的解决方案是将Background 属性从&lt;Button&gt; 标记中移出到&lt;Style&gt;,正如我发布的here :)
  • @Rachel - 不,它不起作用,因为模板触发器仍然比样式设置器具有更高的优先级。
【解决方案2】:

编辑:正如 Rohit 指出的in the comments

这在 Windows 8 上不起作用,因为在声明默认按钮模板的 PresentationFramework 中进行了一些更改。 ...在 Windows 7 中,按钮的默认模板没有该 ControlTemplate 触发器。这就是为什么您发布的代码在 Windows7 上运行良好,但在 Windows 8 及更高版本上无法运行。


Rohit's answer 关于 DependencyProperty Precedence 的原因是正确的,但有一种比覆盖按钮模板更简单的修复方法。

如果您查看DependencyProperty Precedence List,您会注意到&lt;Tag&gt; 中设置的属性比触发属性具有更高的优先级,这就是为什么您的按钮将始终使用您在&lt;Button&gt; 标记中定义的背景.

如果您将Background 属性移动到&lt;Style&gt; 本身,则触发属性将起作用,因为触发属性优先于样式中定义的属性。

<Button Name="register" Content="Register" ...>
    <Button.Style>
        <Style TargetType="Button">
            <Setter Property="Background" Value="#FF0090D6" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

【讨论】:

  • 你试过了吗?这不起作用,因为与模板触发器相比,样式设置器的优先级较低。 (我刚刚做了一个交叉检查,它不起作用)。
  • 是的,我在发布此答案之前对其进行了测试,并且效果很好。我使用的是 VS2010、Windows 7 和 .Net 4.0。您是否为您的 Button 使用任何自定义模板?默认优先级顺序为 &lt;Tag&gt; > TemplatedParent 模板属性 > 隐式样式 > 样式触发器 > 模板触发器 > 样式设置器 > 默认值。如果您有自定义模板,那么您可能必须更改整个 Button.Template,否则我不这么认为。
  • @Rachel 不起作用in my case。我正在使用 VS 2012 Ultimate、Windows 8、.NET 4.5
  • @Rachel - 哦,好吧。它不适用于 Windows 8,因为 PresentationFramework 中声明了默认按钮模板的相同更改。我在 Windows 8.1、.Net 4.5、VS 2013 上进行了测试。在 Windows 7 中,按钮的默认模板没有那个 ControlTemplate 触发器。这就是为什么您发布的代码在 Windows7 上运行良好但在 Windows 8 及更高版本上无法运行的原因。
  • @RohitVats 这解释了,谢谢。我在猜测自己,因为我已经从您那里看到了很多很棒的 WPF 答案,并且您肯定知道您在谈论 WPF 时在说什么,但是我已经对此进行了测试并且效果很好。我会用这些信息更新我的答案:)
【解决方案3】:

您必须覆盖默认模板才能实现此目的。

  <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="50" Height="50" HorizontalContentAlignment="Left" BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="50,0,0,0">
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="Background" Value="Green"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type Button}">
                                <Border Background="{TemplateBinding Background}">
                                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="DarkGoldenrod"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>

希望这会有所帮助。

【讨论】:

  • 不透明度确实适用于我给出的代码,它不会改变背景、边框笔刷等。
【解决方案4】:
 <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="50" Height="50" HorizontalContentAlignment="Left" BorderBrush="{x:Null}" Foreground="{x:Null}" Margin="50,0,0,0">
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="Background" Value="Green"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type Button}">
                                <Border Background="{TemplateBinding Background}">
                                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="DarkGoldenrod"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>

以上代码完美运行, 即使使用此用户也可以在运行时/代码隐藏中更改按钮的背景颜色

【讨论】:

    猜你喜欢
    • 2013-11-09
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多