I have created one custom cotrol
Generic.xaml code is below -
<BitmapImage x:Key="RightImaGE" x:Name="imgD" UriSource="/XYZ.UI_Test;components/Resources/Pfad55-1.png"/>
<Style TargetType="{x:Type local1:CustomButton}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local1:CustomButton}">
<!--<Image Name="imgDefault" Source="{TemplateBinding Image}" Stretch="UniformToFill" />-->
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=ContentOff, RelativeSource={RelativeSource AncestorType=local1:CustomButton}}" Value="SETTINGS">
<Setter Property="Background" Value="Red"/>
<Setter Property="Image.Source" Value="{DynamicResource RightImaGE}" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
CustomButton.cs codebehind is below
public string ContentOff
{
get { return (string)GetValue(ContentOffProperty); }
set { SetValue(ContentOffProperty, value); }
}
public static readonly DependencyProperty ContentOffProperty =
DependencyProperty.Register("ContentOff",
typeof(string), typeof(CustomButton), new PropertyMetadata(null));
public ImageSource Image
{
get { return (ImageSource)GetValue(ImageProperty); }
set { SetValue(ImageProperty, value); }
}
public static readonly DependencyProperty ImageProperty =
DependencyProperty.Register("Image", typeof(ImageSource), typeof(CustomButton), new PropertyMetadata(default(ImageSource)));
I have defined one common style in app.xaml code is below
<Application.Resources>
<Style x:Key="BigButtonStyle" TargetType="local:CustomButton" >
<Setter Property="Control.Background" Value="Transparent"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Margin" Value="1"/>
<Setter Property="FontSize" Value="27"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="#1d5560"/>
<Setter Property="Width" Value="170"/>
<Setter Property="MaxHeight" Value="50"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomButton}">
<Canvas Margin="1">
<Image x:Name="img" Source="Resources/Pfad55.png" Stretch="UniformToFill" >
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="Resources/Pfad55.png" />
<!--<Style.Triggers>
--><!--<Trigger Property="ContentOff" Value="SETTINGS">
<Setter Property="Opacity" Value="0.5" />
</Trigger>--><!--
</Style.Triggers>-->
</Style>
</Image.Style>
</Image>
<ContentPresenter HorizontalAlignment="Center" Content="{TemplateBinding ContentOff}" Canvas.Top="14" Canvas.Left="47"
VerticalAlignment="Center"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now I have Mainwindows.xaml where I am using Custombutton and if button content is Settings it should change different image through trigger than common image which is defined in bigbuttonstyle .
<Controls:CustomButton Grid.Row="8" Grid.Column="2" Style="{StaticResource BigButtonStyle}"
ContentOff="SETTINGS"
Image="Resources/Pfad55-1.png"/>
I tried to use data trigger here but not working and tried property trigger too. But image not changing somehow.
You can use two different style with style inheritance -
<Style x:Key="SmallButtonStyle" TargetType="local:CustomButton" BasedOn="{StaticResource BigButtonStyle}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomButton}">
<Canvas Margin="1">
<Image Source="Resources/Pfad55-1.png" Stretch="UniformToFill" ></Image>
<ContentPresenter HorizontalAlignment="Center" Content="{TemplateBinding ContentOff}" Canvas.Top="14" Canvas.Left="85"
VerticalAlignment="Center"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
then use it
<Controls:CustomButton Grid.Row="8" Grid.Column="2" Style="{StaticResource SmallButtonStyle}"
ContentOff="SETTINGS"
Image="Resources/Pfad55-1.png"/>
It'll be working but without trigger.
Another solution I have added based on your requirement.
Change your Generic.Xaml code like below.
<Style TargetType="{x:Type local1:CustomButton}" >
<Setter Property="FontSize" Value="27"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="#1d5560"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local1:CustomButton}">
<Grid>
<Image Stretch="Fill" >
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="Resources/Pfad55.png" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local1:CustomButton},Path=ContentOff}"
Value="SETTINGS">
<Setter Property="Source"
Value="Resources/Pfad55-1.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<ContentPresenter HorizontalAlignment="Left" Margin="50,0,0,0" Content="{TemplateBinding ContentOff}"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And Chnage your MainWindow.xaml implementation with this
<Controls:CustomButton Grid.Row="8" Grid.Column="2" ContentOff="SETTINGS"/>
You were using App.xaml style with BigButtonStyle , that's why custom control styles and trigger was not firing. Your App.xaml style was locally overriding custom control style and trigger from Generic.xaml.
Related
I have to create a toggle button with two pictures when it's checked or not. When the toggle button isn't enabled the pictures must be gray.
I base my control on a Checkbox and create a new style.
It's working but a have problem with transparency around the pictures. Transparency become white in the gray pictures. picture in gray
Have you an elegante solution? (I found a lot of code behind but this means a lot for such a small problem)
Here my style:
<Style x:Key="OnOffToggle" TargetType="{x:Type local:ToggleButton}">
<Setter Property="Width" Value="60"/>
<Setter Property="Height" Value="60"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="IsChecked" Value="{Binding IsChecked}"/>
<Setter Property="IsEnabled" Value="{Binding IsEnable}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ToggleButton}">
<Grid>
<Image Visibility="{Binding IsEnable, Converter={converters:BoolToVisibilityConverter VisibilityWhenDisable=Hidden}}"
x:Name="checkboxImage" Source="OnOffs_Down.png"/>
<Image Visibility="{Binding IsEnable, Converter={converters:BoolToVisibilityConverter VisibilityWhenDisable=Hidden, IsVisibleWhenEqual=False}}"
Width="{Binding ActualWidth, ElementName=checkboxImage}" Height="{Binding ActualHeight, ElementName=checkboxImage}">
<Image.Source>
<FormatConvertedBitmap Source="{Binding Source, ElementName=checkboxImage}" DestinationFormat="Gray8" />
</Image.Source>
</Image>
<ContentPresenter/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="checkboxImage" Property="Source" Value="OnOffs_Up.png"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I decided to go in the direction that Clemens pointed me. I work with 4 pictures witout transformation.
<Style x:Key="OnOffToggle" TargetType="{x:Type local:ToggleButton}">
<Setter Property="Width" Value="60"/>
<Setter Property="Height" Value="60"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="IsEnabled" Value="{Binding IsEnable}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ToggleButton}">
<Grid>
<Grid Visibility="{Binding IsChecked, Converter={converters:BoolToVisibilityConverter VisibilityWhenDisable=Hidden, IsVisibleWhenEqual=False}}">
<Image Visibility="{Binding IsEnable, Converter={converters:BoolToVisibilityConverter VisibilityWhenDisable=Hidden}}"
Source="OnOffs_Down.png"/>
<Image Visibility="{Binding IsEnable, Converter={converters:BoolToVisibilityConverter VisibilityWhenDisable=Hidden, IsVisibleWhenEqual=False}}"
Source="OnOffs_Down_Disable.png"/>
</Grid>
<Grid Visibility="{Binding IsChecked, Converter={converters:BoolToVisibilityConverter VisibilityWhenDisable=Hidden}}">
<Image Visibility="{Binding IsEnable, Converter={converters:BoolToVisibilityConverter VisibilityWhenDisable=Hidden}}"
Source="OnOffs_Up.png"/>
<Image Visibility="{Binding IsEnable, Converter={converters:BoolToVisibilityConverter VisibilityWhenDisable=Hidden, IsVisibleWhenEqual=False}}"
Source="OnOffs_Up_Disable.png"/>
</Grid>
<ContentPresenter/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have Listbox with a Checkbox. That's the way how I built it:
<Style x:Key="_ListBoxItemStyleCheckBox" TargetType="ListBoxItem">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<CheckBox Name="_Border" Margin="5,2" IsChecked="{TemplateBinding IsSelected}">
<ContentPresenter />
</CheckBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This is my ListBox:
<ListBox
VerticalAlignment="Stretch"
ItemsSource="{Binding Items}"
SelectionMode="Multiple"
ItemContainerStyle="{StaticResource _ListBoxItemStyleCheckBox}">
<ListBoxItem>ListBox Item #1</ListBoxItem>
<ListBoxItem>ListBox Item #2</ListBoxItem>
<ListBoxItem>ListBox Item #3</ListBoxItem>
</ListBox>
When I hover over the Checkbox I get the default color (blue). How can I change this color?
I don't want to change the color of the text. Only the border color of the Checkbox.
Thank you for any help!
You should create template.
CheckBox Template Sample
<Style TargetType="{x:Type CheckBox}" x:Key="chb">
<Setter Property="Margin" Value="5 2 5 2"/>
<Setter Property="IsChecked" Value="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=IsSelected}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="border"
Grid.Column="0"
Width="20"
Height="20"
Background="Transparent"
BorderBrush="Black"
BorderThickness="2">
<Viewbox x:Name="view"
Width="22"
Height="22"
Visibility="Collapsed"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Canvas Width="24" Height="24">
<Path Data="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" Fill="#333333"/>
</Canvas>
</Viewbox>
</Border>
<TextBlock Grid.Column="1"
Text="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=Content}"
Margin="5 0 0 0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Red"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="view" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Connnecting by using StaticResource
<Style x:Key="_ListBoxItemStyleCheckBox" TargetType="ListBoxItem">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<CheckBox Name="_Border" Style="{StaticResource chb}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It will be shown like this.
And I brought Path SVG Data in CheckBox at 'Material Design Icons'.
https://materialdesignicons.com/
<Style x:Key="_ListBoxItemStyleCheckBox" TargetType="ListBoxItem">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<CheckBox Name="_Border" Margin="5,2" IsChecked="{TemplateBinding IsSelected}">
<CheckBox.Resources>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="BorderBrush" Value="LightGray" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Gray" />
</Trigger>
</Style.Triggers>
</Style>
</CheckBox.Resources>
<ContentPresenter />
</CheckBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Css helps you do this,for instance
ListBox tr.rowHover:hover
{
background-color: Yellow;
}
<asp ..... rowstyle-cssclass="rowHover" ...../>
I added a custom style on Mouse Over effect for the button in Resource Dictionary inside the App.xaml file. While on my computer, it is working perfectly but on some PC the button's background is flickering or disappearing on mouseover.
App.xaml Code
<ResourceDictionary>
<Style x:Key="btn-danger" TargetType="{x:Type Button}">
<Setter Property="Background" Value="#d84315" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" Cursor="Hand">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#d9534f" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
How is it being used
<Button Style="{StaticResource btn-danger}" Margin="5" Click="Ok_Button_Click" Height="29" Width="100" Content="{Binding Path=Ok, Source={StaticResource Resources}}"/>
It is necessary to put the trigger under the template property, to border background be changed properly. Try to change the style definition as below:
<ResourceDictionary>
<Style x:Key="btn-danger" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Gray" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" Cursor="Hand">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#d9534f" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
I've got the following style defined in the resources of a UserControl:
<Style x:Key="MenuItemButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Width="40" Height="40" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="1,1,1,1" CornerRadius="3">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Button.Foreground" Value="#666666" />
<Setter Property="Button.Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Button.Cursor" Value="Hand" />
<Setter Property="Button.Foreground" Value="White" />
<Setter Property="Button.Background" Value="#666666" />
</Trigger>
</Style.Triggers>
</Style>
For example I use it like the following:
<Button Click="Toolbar_DocumentMarkup_Click" Name="BtnUnderline" Margin="10,0,0,0" Style="{StaticResource MenuItemButton}">
<fa:FontAwesome VerticalAlignment="Center" Icon="Underline" FontSize="24"/>
</Button>
I need to set the border's width and the height programmatically from the code behind so that the view will be updated on runtime.
What I tried so far:
Access the style through the Resources:
var style = Resources["MenuItemButton"] as Style
but I can't find the right properties in this style object.
Another idea:
Define the width and height as DependencyProperties or implement INotifyPropertyChanged, but I think in my case it's much easier to just set these two values programmatically.
Some oppinions or suggestions on this problem?
Add this to your resources:
<sys:Double x:Key="ButtonHeight">200</sys:Double>
<sys:Double x:Key="ButtonWidth">200</sys:Double>
<Style x:Key="MenuItemButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Width="40" Height="40" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="1,1,1,1" CornerRadius="3">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="{DynamicResource ButtonHeight}" />
<Setter Property="Width" Value="{DynamicResource ButtonWidth}" />
<Setter Property="Button.Foreground" Value="#666666" />
<Setter Property="Button.Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Button.Cursor" Value="Hand" />
<Setter Property="Button.Foreground" Value="White" />
<Setter Property="Button.Background" Value="#666666" />
</Trigger>
</Style.Triggers>
And then in your code behind you change it in your event using:
this.Resources["ButtonHeight"] = ...
and
this.Resources["ButtonWidth"] = ...
EDIT: forgot that of course you need to add the path to system
xmlns:sys="clr-namespace:System;assembly=mscorlib"
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.
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>
<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>
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.
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
<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>