WPF按钮背景悬停颜色

8
我尝试在鼠标悬停时更改XAML中按钮样式的背景颜色。以下是我的当前方法,但它不起作用。仍然使用默认的悬停颜色。
<Style x:Key="AtStyle" TargetType="Button">
        <Setter Property="Background">
            <Setter.Value>
                <SolidColorBrush Color="{StaticResource AtBlue}" />
            </Setter.Value>
        </Setter>
        <Setter Property="Foreground" Value="White" />
        <Setter Property="Padding" Value="12,6" />
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="FontSize" Value="18.667" />
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background">
                    <Setter.Value>
                        <SolidColorBrush Color="Red" />
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

我看到其他解决方案说需要重写控件模板才能实现这一点,但是那些解决方案也需要您定义边框和内容,这似乎是不必要的。在Xaml中定义悬停状态的最简方法是什么?

2个回答

11
我已经根据你的要求创建了一个基于简单样式的按钮,
XAML
<Style  TargetType="Button">
  <Setter Property="Background"
          Value="Blue" />
  <Setter Property="HorizontalAlignment"
          Value="Center" />
  <Setter Property="VerticalAlignment"
          Value="Center" />
  <Setter Property="Foreground"
          Value="White" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Button}">
        <Border x:Name="bg"
                Background="{TemplateBinding Background}"
                BorderThickness="2"
                BorderBrush="White">
          <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                            VerticalAlignment="{TemplateBinding VerticalAlignment}" />
        </Border>
        <ControlTemplate.Triggers>
          <Trigger Property="IsMouseOver"
                   Value="True">
            <Setter Property="Background"
                    Value="Red"
                    TargetName="bg" />
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

这种风格太简单了。它破坏了访问键,甚至不支持禁用状态。而且它也是错误的,因为在 ContentPresenter 上的对齐属性应该使用内容对齐属性。 - Athari
@Athari:感谢您的建议,是的,它太简单了。他们需要包括禁用和键盘聚焦状态的触发器。 - Ravuthasamy

6
让我们来看一下Aero主题默认按钮样式的模板:
<ControlTemplate TargetType="{x:Type ButtonBase}">
    <theme:ButtonChrome Name="Chrome"
            Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
            RenderMouseOver="{TemplateBinding IsMouseOver}"
            RenderPressed="{TemplateBinding IsPressed}"
            SnapsToDevicePixels="True">
        <ContentPresenter
                Margin="{TemplateBinding Padding}"
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                RecognizesAccessKey="True"/>
    </theme:ButtonChrome>
    <ControlTemplate.Triggers>
        <Trigger Property="IsKeyboardFocused" Value="True">
            <Setter TargetName="Chrome" Property="RenderDefaulted" Value="True"/>
        </Trigger>
        <Trigger Property="ToggleButton.IsChecked" Value="True">
            <Setter TargetName="Chrome" Property="RenderPressed" Value="True"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="#ADADAD"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

如您所见,鼠标悬停和按下的颜色是在ButtonChrome属性RenderMouseOverRenderPressed上定义的绑定。由于ButtonChrome的设计方式,它们比Background属性中的任何值优先级高。因此,不幸的是,覆盖已点击或突出显示的按钮的背景颜色的唯一方法是覆盖其模板。


1
这个例子不起作用... 你为什么认为这是比另一个更好的答案?那个是有效的... - Ron van der Heijden
7
@Bondye 这个答案并不是要“起作用”,而是回答“为什么”并提供完全解决问题的指导。 接受的答案“有效”,但只有在非常有限的情况下才有效,并且在需要更复杂的操作时没有帮助。 更详细的分析在我对另一个问题的评论中。 TL;DR:不要简单地复制粘贴;尝试理解并自己完成。 - Athari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接