【问题标题】:Change color of Button when Mouse is over鼠标结束时更改按钮的颜色
【发布时间】:2013-12-03 02:36:47
【问题描述】:

我想在IsMouseOver == True时更改按钮的背景颜色

    <Button Command="{Binding ClickRectangleColorCommand}" Background="{Binding Color, Converter={StaticResource RGBCtoBrushColorsConverter},Mode=TwoWay}" Width="auto" Height="40">
        <TextBlock Foreground="Black" Text="{Binding Color, Converter={StaticResource RGBCColorToTextConveter},Mode=TwoWay}"/>
          <Button.Style>
             <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
               <Style.Triggers>
                  <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="DarkGoldenrod"/>
                  </Trigger>
               </Style.Triggers>
             </Style>
         </Button.Style>
    </Button>

我似乎无法理解为什么这个触发器不起作用。

【问题讨论】:

    标签: wpf xaml user-interface button mouseover


    【解决方案1】:

    试试这个 - 在这个例子中,原始颜色是绿色,鼠标悬停颜色将是 DarkGoldenrod

    <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>
    

    【讨论】:

    • 在 50 秒内 :) 就可以了
    • OP到底做错了什么?我想知道,所以我不会犯同样的错误。
    • WPF 从来没有停止让我惊讶于做如此简单的事情需要多少代码和仪式。谢谢你的回答
    • "WPF 让困难变得琐碎,让琐碎变得困难"
    • 目前还不清楚哪些部分是必要的以及为什么。这里有两个关键点:1)您必须将默认值设置为 Setters,而不是元素上的显式属性,以及 2)您必须在样式中设置模板并将边框绑定到模板。这是因为按钮具有嵌套元素,并且边框覆盖了模板。这很奇怪,但这是适合你的 WPF。
    【解决方案2】:
    <Button Content="Click" Width="200" Height="50">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Background" Value="LightBlue" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="Border" Background="{TemplateBinding Background}">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="LightGreen" TargetName="Border" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Button.Style>
    

    【讨论】:

    • 即:完全用极简主义的重新实现替换样式。 (花了我一段时间来完成这个答案的作用)。很好的答案。我可以看到这种方法的各种应用。它使重复使用库存控制变得更加容易。
    • 接受的答案无效,您的答案有效。对于那些还想更改Foreground的人:默认值=&lt;Setter Property="Foreground" Value="Your color 1" /&gt;,触发值=&lt;Setter TargetName="Border" Property="Button.Foreground" Value="Your color 2" /&gt;
    【解决方案3】:

    正如其他人已经说过的那样,似乎没有什么好的解决方案可以轻松做到这一点。
    但为了保持代码干净,我建议创建一个单独的类来隐藏丑陋的 XAML。

    我们创建了ButtonEx-class后如何使用:

    <Window x:Class="MyApp.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:wpfEx="clr-namespace:WpfExtensions"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <wpfEx:ButtonEx HoverBackground="Red"></wpfEx:ButtonEx>
        </Grid>
    </Window>
    

    ButtonEx.xaml.cs

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    namespace WpfExtensions
    {
        /// <summary>
        /// Standard button with extensions
        /// </summary>
        public partial class ButtonEx : Button
        {
            readonly static Brush DefaultHoverBackgroundValue = new BrushConverter().ConvertFromString("#FFBEE6FD") as Brush;
    
            public ButtonEx()
            {
                InitializeComponent();
            }
    
            public Brush HoverBackground
            {
                get { return (Brush)GetValue(HoverBackgroundProperty); }
                set { SetValue(HoverBackgroundProperty, value); }
            }
            public static readonly DependencyProperty HoverBackgroundProperty = DependencyProperty.Register(
              "HoverBackground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata(DefaultHoverBackgroundValue));
        }
    }
    

    ButtonEx.xaml
    注意:这包含来自 System.Windows.Controls.Button 的所有原始 XAML

    <Button x:Class="WpfExtensions.ButtonEx"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800"
                x:Name="buttonExtension">
        <Button.Resources>
            <Style x:Key="FocusVisual">
                <Setter Property="Control.Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="10" StrokeDashArray="1 2"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
            <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
            <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
            <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
            <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
            <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
            <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
            <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
            <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
        </Button.Resources>
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
                <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
                <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                <Setter Property="BorderThickness" Value="1"/>
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Padding" Value="1"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                                <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsDefaulted" Value="true">
                                    <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                                </Trigger>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="Background" TargetName="border" Value="{Binding Path=HoverBackground, ElementName=buttonExtension}"/>
                                    <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
                                </Trigger>
                                <Trigger Property="IsPressed" Value="true">
                                    <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
                                    <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
                                </Trigger>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
                                    <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
                                    <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Button.Style>
    </Button>
    

    提示: 您可以在 VS Studio 中将名称为“ButtonEx”的 UserControl 添加到您的项目中,然后复制粘贴上面的内容。

    【讨论】:

      【解决方案4】:

      添加 Microsoft_DN 答案,如果有人想为不同颜色的不同按钮重用样式,我们可以使用 hovercolorbgcolor DependencyProperty 创建自定义 Button 类。

      HoverButton.cs

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Media;
      
      namespace StackOverflow
      {
          public class HoverButton : Button
          {
      
              public static readonly DependencyProperty hoverColorProperty = DependencyProperty.Register
                  (
                       "hoverColor",
                       typeof(SolidColorBrush),
                       typeof(HoverButton),
                       new PropertyMetadata(new BrushConverter().ConvertFrom("#5D5D5D"))
                  );
      
              public SolidColorBrush hoverColor
              {
                  get { return (SolidColorBrush)GetValue(hoverColorProperty); }
                  set { SetValue(hoverColorProperty, value); }
              }
      
              public static readonly DependencyProperty bgColorProperty = DependencyProperty.Register
               (
                    "bgColor",
                    typeof(SolidColorBrush),
                    typeof(HoverButton),
                    new PropertyMetadata(new SolidColorBrush(Colors.Red))
               );
      
              public SolidColorBrush bgColor
              {
                  get { return (SolidColorBrush)GetValue(bgColorProperty); }
                  set { SetValue(bgColorProperty, value); }
              }
          }
      }
      

      然后在App.xaml文件中Application.Resources标签内添加如下样式

      <Style TargetType="{x:Type StackOverflow:HoverButton}" x:Key="customButton">
          <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path = bgColor}"/>
          <Setter Property="Template">
              <Setter.Value>
                  <ControlTemplate TargetType="{x:Type Button}">
                      <Border Background="{TemplateBinding Background}">
                          <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"  Margin="{TemplateBinding Padding}"/>
                      </Border>
                  </ControlTemplate>
              </Setter.Value>
          </Setter>
          <Style.Triggers>
              <Trigger Property="IsMouseOver" Value="True">
                  <Setter Property="Background" Value ="{Binding RelativeSource={RelativeSource Self}, Path = hoverColor}" />
              </Trigger>
          </Style.Triggers>
      </Style>
      

      我们可以使用 HoverButton 中的样式

      <myApp:HoverButton Height="20" Width="20" Style="{StaticResource customButton}" bgColor="Orange" hoverColor="Blue">
      </myApp:HoverButton>
      

      因为 HoverButton 没有使用我们需要添加的项目命名空间

      xmlns:myApp = "clr-namespace:StackOverflow"app.xaml 中的 Application 标记和 MainWindow.xaml 文件中的 Window 标记中。

      示例:https://github.com/ayush1920/Stackoverflow/tree/main/WPF%20HoverButton

      【讨论】:

        【解决方案5】:
        <Button Background="#FF4148" BorderThickness="0" BorderBrush="Transparent">
             <Border HorizontalAlignment="Right" BorderBrush="#FF6A6A" BorderThickness="0>
             <Border.Style>
                 <Style TargetType="Border">
                     <Style.Triggers>
                         <Trigger Property="IsMouseOver" Value="True">
                             <Setter Property="Background" Value="#FF6A6A" />
                         </Trigger>
                     </Style.Triggers>
                 </Style>
              </Border.Style>
              <StackPanel Orientation="Horizontal">
                   <Image  RenderOptions.BitmapScalingMode="HighQuality"   Source="//ImageName.png"   />
              </StackPanel>
              </Border>
          </Button>
        

        【讨论】:

          猜你喜欢
          • 2012-08-16
          • 2016-12-11
          • 1970-01-01
          • 2012-06-19
          • 2018-07-20
          • 2017-11-29
          相关资源
          最近更新 更多