Change color of Button when Mouse is over

WpfXamlUser InterfaceButtonMouseover

Wpf Problem Overview


I want to change the background color of a button when 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>

I can't seem to understand why this trigger isn't working.

Wpf Solutions


Solution 1 - Wpf

Try this- In this example Original color is green and mouseover color will be 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>

Solution 2 - Wpf

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

Solution 3 - Wpf

As others already said, there seems to be no good solution to do that easily.
But to keep your code clean I suggest creating a seperate class that hides the ugly XAML.

How to use after we created the 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
Note: This contains all the original XAML from System.Windows.Controls.Button

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

Tip: You can add an UserControl with name "ButtonEx" to your project in VS Studio and then copy paste the stuff above in.

Solution 4 - Wpf

Adding on Microsoft_DN answer, if anyone wants to reuse the style for different buttons with different color we can create a custom Button class with hovercolor and bgcolor DependencyProperty.

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); }
        }
    }
}

Then add the following style in App.xaml file inside Application.Resources tag

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

The we can use the style as in HoverButton

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

Because HoverButton is not using the project namespace we need to add

xmlns:myApp = "clr-namespace:StackOverflow" in both Application tag in app.xaml and Window tag in MainWindow.xaml file.

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

Solution 5 - Wpf

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGiladView Question on Stackoverflow
Solution 1 - WpfMicrosoft DNView Answer on Stackoverflow
Solution 2 - WpfTrung MessiView Answer on Stackoverflow
Solution 3 - WpfSebastian AxView Answer on Stackoverflow
Solution 4 - WpfAyush KumarView Answer on Stackoverflow
Solution 5 - Wpfshaiju mathewView Answer on Stackoverflow