How do you change Background for a Button MouseOver in WPF? - wpf

I have a button on my page with this XAML:
<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="Button">
<Setter Property="Background" Value="Green"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
But when I put mouse over my button, button's background changes to default windows gray background.What's The Problem?
This is the button picture before and after mouseover:
Before:
After:

To remove the default MouseOver behaviour on the Button you will need to modify the ControlTemplate. Changing your Style definition to the following should do the trick:
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
EDIT: It's a few years late, but you are actually able to set the border brush inside of the border that is in there. Idk if that was pointed out but it doesn't seem like it was...

All of the answers so far involve completely replacing the default button behavior with something else. However, IMHO it is useful and important to understand that it's possible to change just the part you care about, by editing the existing, default template for a XAML element.
In the case of dealing with the hover effect on a WPF button, the change in appearance in a WPF Button element is caused by a Trigger in the default style for the Button, which is based on the IsMouseOver property and sets the Background and BorderBrush properties of the top-level Border element in the control template. The Button element's background is underneath the Border element's background, so changing the Button.Background property doesn't prevent the hover effect from being seen.
With some effort, you could override this behavior with your own setter, but because the element you need to affect is in the template and not directly accessible in your own XAML, that approach would be difficult and IMHO overly complex.
Another option would be to make use the graphic as the Content for the Button rather than the Background. If you need additional content over the graphic, you can combine them with a Grid as the top-level object in the content.
However, if you literally just want to disable the hover effect entirely (rather than just hiding it), you can use the Visual Studio XAML Designer:
While editing your XAML, select the "Design" tab.
In the "Design" tab, find the button for which you want to disable the effect.
Right-click that button, and choose "Edit Template/Edit a Copy...". Select in the prompt you get where you want the new template resource to be placed. This will appear to do nothing, but in fact the Designer will have added new resources where you told it, and changed your button element to reference the style that uses those resources as the button template.
Now, you can go edit that style. The easiest thing is to delete or comment-out (e.g. Ctrl+E, C) the <Trigger Property="IsMouseOver" Value="true">...</Trigger> element. Of course, you can make any change to the template you want at that point.
When you're done, the button style will look something like this:
<p:Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</p: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"/>
<p:Style x:Key="ButtonStyle1" 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="{StaticResource Button.MouseOver.Background}"/>
<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>
</p:Style>
(Note: you can omit the p: XML namespace qualifications in the actual codeā€¦I provide them here only because the Stack Overflow XML code formatter gets confused by <Style/> elements that don't have a fully-qualified name with XML namespace.)
If you want to apply the same style to other buttons, you can just right-click them and choose "Edit Template/Apply Resource" and select the style you just added for the first button. You can even make that style the default style for all buttons, using the normal techniques for applying a default style to elements in XAML.

This worked well for me.
Button Style
<Style x:Key="TransparentStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Background="Transparent">
<ContentPresenter></ContentPresenter>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Button
<Button Style="{StaticResource TransparentStyle}" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25"
Command="{Binding CloseWindow}">
<Button.Content >
<Grid Margin="0 0 0 0">
<Path Data="M0,7 L10,17 M0,17 L10,7" Stroke="Blue" StrokeThickness="2" HorizontalAlignment="Center" Stretch="None" />
</Grid>
</Button.Content>
</Button>
Notes
The button displays a little blue cross, much like the one used to close a window.
By setting the background of the grid to "Transparent", it adds a hittest, which means that if the mouse is anywhere over the button, then it will work. Omit this tag, and the button will only light up if the mouse is over one of the vector lines in the icon (this is not very usable).

Just want to share my button style from my ResourceDictionary that i've been using.
You can freely change the onHover background at the style triggers.
"ColorAnimation To = *your desired BG(i.e #FFCEF7A0)". The button BG will also automatically revert to its original BG after the mouseOver state.You can even set how fast the transition.
Resource Dictionary
<Style x:Key="Flat_Button" TargetType="{x:Type Button}">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="50"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="FontFamily" Value="Arial Narrow"/>
<Setter Property="FontSize" Value="12px"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Opacity="1" Color="White"/>
</Setter.Value>
</Setter>
<Setter Property="Background" >
<Setter.Value>
<SolidColorBrush Opacity="1" Color="#28C2FF" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border"
SnapsToDevicePixels="True"
BorderThickness="1"
Padding="4,2"
BorderBrush="Gray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="#D2F898"
Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" Duration="0:0:0.25" AutoReverse="False" RepeatBehavior="1x"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
all you have to do is call the style.
Example Implementation
<Button Style="{StaticResource Flat_Button}" Height="Auto"Width="Auto">
<StackPanel>
<TextBlock Text="SAVE" FontFamily="Arial" FontSize="10.667"/>
</StackPanel>
</Button>

A slight more difficult answer that uses ControlTemplate and has an animation effect
(adapted from https://learn.microsoft.com/en-us/dotnet/framework/wpf/controls/customizing-the-appearance-of-an-existing-control)
In your resource dictionary define a control template for your button like this one:
<ControlTemplate TargetType="Button" x:Key="testButtonTemplate2">
<Border Name="RootElement">
<Border.Background>
<SolidColorBrush x:Name="BorderBrush" Color="Black"/>
</Border.Background>
<Grid Margin="4" >
<Grid.Background>
<SolidColorBrush x:Name="ButtonBackground" Color="Aquamarine"/>
</Grid.Background>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,5,4,4"/>
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ButtonBackground" Storyboard.TargetProperty="Color" To="Red"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
in your XAML you can use the template above for your button as below:
Define your button
<Button Template="{StaticResource testButtonTemplate2}"
HorizontalAlignment="Center" VerticalAlignment="Center"
Foreground="White">My button</Button>
Hope it helps

For change button style
1st: define resource styles
<Window.Resources>
<Style x:Key="OvergroundIn" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FF16832F">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FF06731F">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="OvergroundOut" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FFF35E5E">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#FFE34E4E">
<ContentPresenter TextBlock.Foreground="White" TextBlock.TextAlignment="Center" Margin="0,8,0,0" ></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
2nd define button code
<Border Grid.Column="2" BorderBrush="LightGray" BorderThickness="2" CornerRadius="3" Margin="2,2,2,2" >
<Button Name="btnFichar" BorderThickness="0" Click="BtnFichar_Click">
<Button.Content>
<Grid>
<TextBlock Margin="0,7,0,7" TextAlignment="Center">Fichar</TextBlock>
</Grid>
</Button.Content>
</Button>
</Border>
3th code behind
public void ShowStatus()
{
switch (((MainDto)this.DataContext).State)
{
case State.IN:
this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(243, 94, 94));
this.btnFichar.Style = Resources["OvergroundIn"] as Style;
this.btnFichar.Content = "Fichar Salida";
break;
case State.OUT:
this.btnFichar.BorderBrush = new SolidColorBrush(Color.FromRgb(76, 106, 83));
this.btnFichar.Style = Resources["OvergroundOut"] as Style;
this.btnFichar.Content = "Fichar Entrada";
break;
}
}

Related

Change the background colour of a CheckBox using DataTriggers

I'd like the background of my CheckBox to change colour depending on if it matches a pre-defined bool (not just if it's Checked or Unchecked). The problem is that this looks poor if you do it to the CheckBox alone, so I've wrapped the CheckBox in a Grid and set the background of the Grid instead. My issue now is that I want to pull out this style so I can reuse it for my other Checkbox
Here is my XAML:
<Grid Margin="5 10 0 0">
<CheckBox Name="cbJimbo" Content="JIMBO" FontSize="12"
IsChecked="{Binding MyObject.Jimbo}"
Style="{StaticResource CheckBoxStyle}"/>
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cbJimbo, Path=Background}" Value="Yellow">
<Setter Property="Background" Value="Yellow" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
What is the best way to refactor this?
In the interest of completeness (Although not entirely relevant) here is the CheckBox style, which determines if the CheckBox matches the default value and then sets the CheckBox background in a too subtle fashion. Also relevant as my Grid is currently bound to the background of this Checkbox:
<Style x:Key="ValidationCheckBox" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<AdornedElementPlaceholder x:Name="placeholder"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)/ErrorContent.ErrorType}" Value="{x:Static wrapper:ErrorTypeEnum.Default}">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
</Style>
Making Your Style Reusable
If you want create a separate style for the Grid, the element name binding is problematic, since the same name might already exist in this namescope. An alternative, although not very robust is to explicitly specify the child that the CheckBox is via index. It is advisible to trigger on the real property that triggers the CheckBox, too, so you do not have to change the brush to in both style. It also makes the reason for the color change apparent.
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Children[0].(CheckBox.Background)}" Value="Yellow">
<Setter Property="Background" Value="Yellow" />
</DataTrigger>
</Style.Triggers>
</Style>
Changing the Control Template
As you might know, the visual appearance and states of a control are defined in a ControlTemplate. Instead of building a Grid around the CheckBox, you could extract its default styleand control template and adapt it, so that it has the same backgroud as the check mark box. There is already a Grid as template root, but its background is set to Transparent. If we replace that with a TemplateBinding to the Background property, it looks as expected.
<Grid x:Name="templateRoot" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
This is the whole and adapted control template for CheckBox.
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="OptionMarkFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="14,0,0,0" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="OptionMark.Static.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="OptionMark.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="OptionMark.Static.Glyph" Color="#FF212121"/>
<SolidColorBrush x:Key="OptionMark.MouseOver.Background" Color="#FFF3F9FF"/>
<SolidColorBrush x:Key="OptionMark.MouseOver.Border" Color="#FF5593FF"/>
<SolidColorBrush x:Key="OptionMark.MouseOver.Glyph" Color="#FF212121"/>
<SolidColorBrush x:Key="OptionMark.Pressed.Background" Color="#FFD9ECFF"/>
<SolidColorBrush x:Key="OptionMark.Pressed.Border" Color="#FF3C77DD"/>
<SolidColorBrush x:Key="OptionMark.Pressed.Glyph" Color="#FF212121"/>
<SolidColorBrush x:Key="OptionMark.Disabled.Background" Color="#FFE6E6E6"/>
<SolidColorBrush x:Key="OptionMark.Disabled.Border" Color="#FFBCBCBC"/>
<SolidColorBrush x:Key="OptionMark.Disabled.Glyph" Color="#FF707070"/>
<Style x:Key="CheckBoxStyle" TargetType="{x:Type CheckBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource OptionMark.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource OptionMark.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid x:Name="templateRoot" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="checkBoxBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid x:Name="markGrid">
<Path x:Name="optionMark" Data="F1 M 9.97498,1.22334L 4.6983,9.09834L 4.52164,9.09834L 0,5.19331L 1.27664,3.52165L 4.255,6.08833L 8.33331,1.52588e-005L 9.97498,1.22334 Z " Fill="{StaticResource OptionMark.Static.Glyph}" Margin="1" Opacity="0" Stretch="None"/>
<Rectangle x:Name="indeterminateMark" Fill="{StaticResource OptionMark.Static.Glyph}" Margin="2" Opacity="0"/>
</Grid>
</Border>
<ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual}"/>
<Setter Property="Padding" Value="4,-1,0,0"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.MouseOver.Border}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.MouseOver.Glyph}"/>
<Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.MouseOver.Glyph}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Disabled.Border}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.Disabled.Glyph}"/>
<Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.Disabled.Glyph}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="checkBoxBorder" Value="{StaticResource OptionMark.Pressed.Border}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource OptionMark.Pressed.Glyph}"/>
<Setter Property="Fill" TargetName="indeterminateMark" Value="{StaticResource OptionMark.Pressed.Glyph}"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Opacity" TargetName="optionMark" Value="1"/>
<Setter Property="Opacity" TargetName="indeterminateMark" Value="0"/>
</Trigger>
<Trigger Property="IsChecked" Value="{x:Null}">
<Setter Property="Opacity" TargetName="optionMark" Value="0"/>
<Setter Property="Opacity" TargetName="indeterminateMark" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Creating Custom Controls
If you intend to use the same control hierarchy in the same way in multiple places, the original style will not save you from lots of code duplication that makes your code less maintainable. In such scenarios, consider creating a UserControl which encapsulates the control as single, reusable control instead.
The simplest way to create a control in WPF is to derive from UserControl. When you build a control that inherits from UserControl, you add existing components to the UserControl, name the components, and reference event handlers in WPF.
If built correctly, a UserControl can take advantage of the benefits of rich content, styles, and triggers. However, if your control inherits from UserControl, people who use your control will not be able to use a DataTemplate or ControlTemplate to customize its appearance.
If your control is not only a composition of other controls, but a fully-fledged new control with custom behavior and control template as well as theming support, you would create a custom control instead. For more information and differences refer to Control authoring overview.

WPF. Prevent checkbox inside button from firing click event

I have a button with a checkbox inside in WPF. I want to be able to check the checkbox without firing the click event of the button.
My problem is that, currently, the click event is fired whether I press the checkbox itself or its label, behavior I don't want. I only want to raise the click event if I press somewhere in the red zone.
Is there a way to prevent this?
This is my code by now:
Style for the checkbox:
<Style x:Key="FilledCheckBox" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Border x:Name="Border"
Width="15"
Height="15"
CornerRadius="1"
BorderThickness="1">
<Border.BorderBrush>
<SolidColorBrush Color="Gray"/>
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush Color="White"/>
</Border.Background>
</Border>
</BulletDecorator.Bullet>
<ContentPresenter Margin="5,0,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
RecognizesAccessKey="True" />
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" TargetName="Border" Value="Green"/>
<Setter Property="BorderBrush" TargetName="Border" Value="Green"/>
<Setter Property="Foreground" Value="Green"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Style for the button (with the checkbox inside):
<Style x:Key="RoundCornerButtonWithCheck" TargetType="{x:Type Button}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Width" Value="120"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Button.Effect">
<Setter.Value>
<DropShadowEffect Color="Black" Direction="280" ShadowDepth="2" BlurRadius="5" Opacity="0.2" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="border" CornerRadius="15" BorderBrush="Black" BorderThickness="0" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
TextElement.FontWeight="SemiBold">
</ContentPresenter>
</Border>
<CheckBox x:Name="checkbox" Grid.Column="0" VerticalAlignment="Center" Margin="20,0,0,0" Style="{StaticResource FilledCheckBox}"></CheckBox>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="border">
<Setter.Value>
<SolidColorBrush Color="Gold" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="#FF33962B"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" TargetName="grid" Value="0.25"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The button in the template:
<Button Name="deleteButton" Style="{StaticResource RoundCornerButtonWithCheck}" Content="{Binding Source={x:Static localization:Resources.Delete}, Converter={StaticResource CharacterCasingConverter}}" VerticalAlignment="Center" HorizontalAlignment="Left" Background="Red" Foreground="White" Margin="80,0,80,30" Click="DeleteClick"></Button>
Is there a way to prevent this?
You can't really prevent the built-in Button control itself from handling the click without cancelling the PreviewMouseLeftButtonDown event but you can implement the event handler to ignore clicks on the CheckBox:
private void SaveClick(object sender, RoutedEventArgs e)
{
if (!(e.OriginalSource is CheckBox))
{
//handle click outside the CheckBox...
}
}

Changing the background of a WPF button to a solid color when mouse is rolled over? [duplicate]

My problem is that in WPF, whenever I try and change the colour of a button's background using triggers or animations, the default mouseover effect (of being grey with that orange glow) seems to take priority.
After extensive searches I'm clueless as to how to remove this effect.
This is similar to the solution referred by Mark Heath but with not as much code to just create a very basic button, without the built-in mouse over animation effect. It preserves a simple mouse over effect of showing the button border in black.
The style can be inserted into the Window.Resources or UserControl.Resources section for example (as shown).
<UserControl.Resources>
<!-- This style is used for buttons, to remove the WPF default 'animated' mouse over effect -->
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<!-- usage in xaml -->
<Button Style="{StaticResource MyButtonStyle}">Hello!</Button>
Just to add a very simple solution, that was good enough for me, and I think addresses the OP's issue. I used the solution in this answer except with a regular Background value instead of an image.
<Style x:Key="SomeButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
No re-templating beyond forcing the Background to always be the Transparent background from the templated button - mouseover no longer affects the background once this is done. Obviously replace Transparent with any preferred value.
You need to create your own custom button template to have full control over the appearance in all states. Here's a tutorial.
The Muffin Man had a very simple answer which worked for me.
To add a little more specific direction, at least for VS 2013:
Right-click the control
Select Edit Template => Edit a copy...
I selected 'Application' for where to save the style
From here you can directly edit App.xaml and see the intuitively named properties. For my purposes, I just set RenderMouseOver="False"
Then, in the MainWindow.xaml or wherever your GUI is, you can paste the new style at the end of the Button tag, e.g. ... Style="{DynamicResource MouseOverNonDefault}"/>
This Link helped me alot
http://www.codescratcher.com/wpf/remove-default-mouse-over-effect-on-wpf-buttons/
Define a style in UserControl.Resources or Window.Resources
<Window.Resources>
<Style x:Key="MyButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border" BorderThickness="0" BorderBrush="Black" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.8" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Then add the style to your button this way Style="{StaticResource MyButton}"
<Button Name="btnSecond" Width="350" Height="120" Margin="15" Style="{StaticResource MyButton}">
<Button.Background>
<ImageBrush ImageSource="/Remove_Default_Button_Effect;component/Images/WithStyle.jpg"></ImageBrush>
</Button.Background>
</Button>
If someone doesn't want to override default Control Template then here is the solution.
You can create DataTemplate for button which can have TextBlock and then you can write Property trigger on IsMouseOver property to disable mouse over effect. Height of TextBlock and Button should be same.
<Button Background="Black" Margin="0" Padding="0" BorderThickness="0" Cursor="Hand" Height="20">
<Button.ContentTemplate>
<DataTemplate>
<TextBlock Text="GO" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" TextDecorations="Underline" Margin="0" Padding="0" Height="20">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value="True">
<Setter Property= "Background" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</Button.ContentTemplate>
</Button>
An extension on dodgy_coder's answer which adds support for..
Maintaining WPF button style
Adds support for IsSelected and hover, i.e. a toggled button
<Style x:Key="Button.Hoverless" TargetType="{x:Type ButtonBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border Name="border"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="Selector.IsSelected" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#FFBEE6FD" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="Selector.IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#BB90EE90" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="False" />
<Condition Property="Selector.IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="LightGreen" />
</MultiTrigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="border" Property="Opacity" Value="0.95" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
examples..
<Button Content="Wipe On" Selector.IsSelected="True" />
<Button Content="Wipe Off" Selector.IsSelected="False" />
Using a template trigger:
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="White"></Setter>
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF Trigger Not Working As Intended

I want a red button that turns black when the mouse hovers over it.
<Button Content="Hover me" Grid.Column="3" Grid.Row="3">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
However, my problem is that when I hover over the button, it turns into the default Windows style with a gradient gray appearance.
Try it
<Window.Resources>
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter x:Name="PART_Content"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
TextElement.Foreground="{TemplateBinding Foreground}"></ContentPresenter> </Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
and apply the custom Style as following
<Button Content="Hover me" Style="{StaticResource MyButtonStyle}" Height="30" Width="100"/>
The reason is the default Aero style of a Button. It has a chrome defined in ControlTemplate, which has it own behavior on various mouse events. So That over write your trigger call.
So you must override default ControlTemplate of Button to achieve your desired result.

How to remove default mouse-over effect on WPF buttons?

My problem is that in WPF, whenever I try and change the colour of a button's background using triggers or animations, the default mouseover effect (of being grey with that orange glow) seems to take priority.
After extensive searches I'm clueless as to how to remove this effect.
This is similar to the solution referred by Mark Heath but with not as much code to just create a very basic button, without the built-in mouse over animation effect. It preserves a simple mouse over effect of showing the button border in black.
The style can be inserted into the Window.Resources or UserControl.Resources section for example (as shown).
<UserControl.Resources>
<!-- This style is used for buttons, to remove the WPF default 'animated' mouse over effect -->
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<!-- usage in xaml -->
<Button Style="{StaticResource MyButtonStyle}">Hello!</Button>
Just to add a very simple solution, that was good enough for me, and I think addresses the OP's issue. I used the solution in this answer except with a regular Background value instead of an image.
<Style x:Key="SomeButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
No re-templating beyond forcing the Background to always be the Transparent background from the templated button - mouseover no longer affects the background once this is done. Obviously replace Transparent with any preferred value.
You need to create your own custom button template to have full control over the appearance in all states. Here's a tutorial.
The Muffin Man had a very simple answer which worked for me.
To add a little more specific direction, at least for VS 2013:
Right-click the control
Select Edit Template => Edit a copy...
I selected 'Application' for where to save the style
From here you can directly edit App.xaml and see the intuitively named properties. For my purposes, I just set RenderMouseOver="False"
Then, in the MainWindow.xaml or wherever your GUI is, you can paste the new style at the end of the Button tag, e.g. ... Style="{DynamicResource MouseOverNonDefault}"/>
This Link helped me alot
http://www.codescratcher.com/wpf/remove-default-mouse-over-effect-on-wpf-buttons/
Define a style in UserControl.Resources or Window.Resources
<Window.Resources>
<Style x:Key="MyButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border" BorderThickness="0" BorderBrush="Black" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.8" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Then add the style to your button this way Style="{StaticResource MyButton}"
<Button Name="btnSecond" Width="350" Height="120" Margin="15" Style="{StaticResource MyButton}">
<Button.Background>
<ImageBrush ImageSource="/Remove_Default_Button_Effect;component/Images/WithStyle.jpg"></ImageBrush>
</Button.Background>
</Button>
If someone doesn't want to override default Control Template then here is the solution.
You can create DataTemplate for button which can have TextBlock and then you can write Property trigger on IsMouseOver property to disable mouse over effect. Height of TextBlock and Button should be same.
<Button Background="Black" Margin="0" Padding="0" BorderThickness="0" Cursor="Hand" Height="20">
<Button.ContentTemplate>
<DataTemplate>
<TextBlock Text="GO" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" TextDecorations="Underline" Margin="0" Padding="0" Height="20">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value="True">
<Setter Property= "Background" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</Button.ContentTemplate>
</Button>
An extension on dodgy_coder's answer which adds support for..
Maintaining WPF button style
Adds support for IsSelected and hover, i.e. a toggled button
<Style x:Key="Button.Hoverless" TargetType="{x:Type ButtonBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border Name="border"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="Selector.IsSelected" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#FFBEE6FD" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="Selector.IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#BB90EE90" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="False" />
<Condition Property="Selector.IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="LightGreen" />
</MultiTrigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="border" Property="Opacity" Value="0.95" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
examples..
<Button Content="Wipe On" Selector.IsSelected="True" />
<Button Content="Wipe Off" Selector.IsSelected="False" />
Using a template trigger:
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="White"></Setter>
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Resources