Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you change Background for a Button MouseOver in 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:
Before
After:
After

like image 913
Sepehr Mohammadi Avatar asked Jun 23 '13 09:06

Sepehr Mohammadi


2 Answers

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

like image 130
Richard E Avatar answered Sep 22 '22 15:09

Richard E


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:

  1. While editing your XAML, select the "Design" tab.
  2. In the "Design" tab, find the button for which you want to disable the effect.
  3. 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.
  4. 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.

like image 31
Peter Duniho Avatar answered Sep 23 '22 15:09

Peter Duniho