I'm trying to disable the MouseOver effect on buttons, or at least change the colour of it, in WPF.
I'm using the following style:
<Style x:Key="Borderless" TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Button Background="{TemplateBinding Control.Background}"
Focusable="False">
<ContentPresenter
Margin="{TemplateBinding Control.Padding}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
RecognizesAccessKey="True"
Content="{TemplateBinding ContentControl.Content}" />
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
in Window.Resources, which I thought would override all the default behaviours. But it doesn't.
Any suggestions?
Look what your control template boils down to:
<ControlTemplate TargetType="{x:Type Button}">
<Button>
<ContentPresenter/>
</Button>
</ControlTemplate>
You're saying, "I want to replace the look of my button with... a button." The usage of the ControlTemplate is to replace the visual tree of a control. So you are replacing the visual tree of the existing button with another button. If you want to start a button from scratch, try using the SimpleStyles button:
<Style TargetType="{x:Type Button}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="23"/>
<Setter Property="MinWidth" Value="75"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border" CornerRadius="2" BorderThickness="1"
Background="#C0C0C0"
BorderBrush="#404040">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter TargetName="Border"
Property="BorderBrush" Value="#202020" />
</Trigger>
<Trigger Property="IsDefaulted" Value="true">
<Setter TargetName="Border"
Property="BorderBrush" Value="#202020" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border"
Property="Background" Value="#808080" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border"
Property="Background" Value="#E0E0E0" />
<Setter TargetName="Border"
Property="BorderBrush" Value="#606060" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border"
Property="Background" Value="#EEEEEE" />
<Setter TargetName="Border"
Property="BorderBrush" Value="#AAAAAA" />
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Notice that this template creates a button the simplest possible way: a border that contains the button content. It does not use another button embedded inside the template.
Related
I want to change the default color of the button for IsMouseOver and IsPressed, but something is wrong with my code. It's not applying, buttons still have their default style.
This is my code:
<Style x:Key="PanelButtonStyle" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="Purple" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#479DE0"/>
</Trigger>
</Style.Triggers>
</Style>
And on the button...
<Button Style="{StaticResource PanelButtonStyle}" .../>
The IsMouseOver and IsPressed brushes are hardcoded into the default ControlTemplate for the Button.
You could copy the default template into your XAML markup by right-clicking on the Button element in design mode in Visual Studio or in Blend and choose Edit Template->Edit a Copy.
You would then edit the template as per your requirements:
<Style x:Key="PanelButtonStyle" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Style.Resources>
<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>
</Style>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#479DE0"/>
<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"/>
</Style.Resources>
<Setter Property="Background" Value="Purple" />
<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>
</Style>
Just adding triggers to the Style without modifying the template won't work because of how the default template is defined.
Button has already triggers to change the visual state defined internally.
You have to override the default template to override the default triggers (See: Styles and templates):
<Style x:Key="PanelButtonStyle" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Purple" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#479DE0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
BorderBrush color of my button template does not change to Yellow. Please help.
<Style x:Key="someName" TargetType="{x:Type Button}">
<Setter Property="Background" Value="LightGreen"/>
<Setter Property="BorderBrush" Value="Yellow"/>
<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="Green"/>
</Trigger>
</Style.Triggers>
</Style>
You have to bind the BorderBrush to the templated control via TemplateBinding so that it applies the value defined in your style. Additionally, you have to set add a BorderThickness of at least one the same way, otherwise there is no border.
<Style x:Key="someName" TargetType="{x:Type Button}">
<Setter Property="Background" Value="LightGreen"/>
<Setter Property="BorderBrush" Value="Yellow"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
As a general note, a control template defines all parts and states of a control and transitions between them. Your control template only defines the Mouse Over state apart from the normal state. Missing states may harm the user experience. You can find a list of all parts and states for a button in the documentation.
It is recommendable to extract the default control template or style for a control with Blend or Visual Studio first and adapting that. I have extracted the default style and merged it with your style. You just have to adapt the Disabled and Pressed colors.
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="LightGreen"/>
<Setter Property="BorderBrush" Value="Yellow"/>
<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" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" 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="Green"/>
<Setter Property="BorderBrush" TargetName="border" Value="Yellow"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="#FFC4E5F6"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FF2C628B"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="#FFF4F4F4"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FFADB2B5"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have a few buttons on an interface that I've customized the color on. When I mouse over them, they get tinted with that blue that Microsoft uses on things in Windows. It looks great, just not on my color combination (black and gold).
How do I eliminate this highlighting on click behavior? I need to do this for all of my buttons, which inherit from a base style:
<Style x:Key="ContentControlElementsStyle" TargetType="ContentControl">
<Setter Property="FontFamily" Value="Segoe UI"/>
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="#F1B82D"/>
<Setter Property="BorderBrush" Value="#F1B82D"/>
</Style>
Use the following button style.
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}" >
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<!--<Trigger Property="Button.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="#FFBEE6FD"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FF3C7FB1"/>
</Trigger>-->
<!--<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="border" Value="#FFC4E5F6"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FF2C628B"/>
</Trigger>-->
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Background" TargetName="border" Value="#FFBCDDEE"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FF245A83"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" TargetName="border" Value="#FFF4F4F4"/>
<Setter Property="BorderBrush" TargetName="border" Value="#FFADB2B5"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I commented the Triggers which cause color change in mouse over and pressed state.
Something along the lines of:
<Style.Triggers>
<Trigger Property="Button.IsPressed" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="MyAwesomeClickedPicture.png" Height="32" Width="32" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="MyAwesomePicture.png" Height="32" Width="32" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
But in your case I guess you'd want to set a color not an image like I did
I'm trying to change the background colour of a button's style in xaml on hover
This is my current approach, but it doesn't work. The default hover colour is being used
<Style x:Key="AtStyle" TargetType="Button">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="{StaticResource AtBlue}" />
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="White" />
<Setter Property="Padding" Value="12,6" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="FontSize" Value="18.667" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Red" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
I've seen other solutions that say that you need to override the Control template to achieve this, but those solutions also require you define the border and the content as well which seems unnecessary. What is the minimal approach to defining a hover state in Xaml?
I have created simple style based button based on your requirement,
XAML
<Style TargetType="Button">
<Setter Property="Background"
Value="Blue" />
<Setter Property="HorizontalAlignment"
Value="Center" />
<Setter Property="VerticalAlignment"
Value="Center" />
<Setter Property="Foreground"
Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="bg"
Background="{TemplateBinding Background}"
BorderThickness="2"
BorderBrush="White">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="Red"
TargetName="bg" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Let's look at the template of the default button style for Aero theme:
<ControlTemplate TargetType="{x:Type ButtonBase}">
<theme:ButtonChrome Name="Chrome"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderPressed="{TemplateBinding IsPressed}"
SnapsToDevicePixels="True">
<ContentPresenter
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
RecognizesAccessKey="True"/>
</theme:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="Chrome" Property="RenderDefaulted" Value="True"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter TargetName="Chrome" Property="RenderPressed" Value="True"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
As you can see, the mouse-over and pressed colors are defined as bindings on the ButtonChrome's properties RenderMouseOver and RenderPressed. The way ButtonChrome is designed, they take priority over any values from the Background property. Therefore, unfortunately, the only way to override background color of a clicked or highlighted button is to override its template.
I'm trying to make custom buttons for my application but it's not going very well.
I have the following XAML just for testing purposes:
<Style x:Key="DefBtn" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<Grid >
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" Name="content"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Yellow" />
<Setter Property="Foreground" Value="#FF4788c8" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
-
<Button x:Name="btnCancelTimer" Content="{Binding [LangResources.timerDetail4], FallbackValue=Cancel Timer, Mode=OneWay, Source={StaticResource localisation}}" Margin="231,0,231,32.04" VerticalAlignment="Bottom" IsCancel="True" FontSize="13.333" Click="BtnCancelTimerClick" Cursor="Hand" Foreground="#FF666666" Background="White" FontFamily="Arial" FontWeight="Bold" Width="115" Height="24" Style="{DynamicResource DefBtn}" />
I'm trying to achieve a button styling exactly like this, also including mouseover and pressed stylings on the button.
Can anyone help/guide me on how I could achieve this?
Thanks
Try using this style
<Style x:Key="DefBtn" TargetType="{x:Type Button}">
<Setter Property="Background" Value="#FFF5F5F5"/>
<Setter Property="BorderBrush" Value="#FFDCDCDC"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="#FF666666"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="11"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="8,7"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="1"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<!--TODO: Set the right colors-->
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Yellow" />
<Setter Property="Foreground" Value="#FF4788c8" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<!--Some setters here-->
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I don't have too keen of an eye for fonts, but Arial seems to be very close. KaXaml shows this style as follows:
Also, you need to check the setters for the MouseOver, Pressed and Disabled (IsEnabled=false) triggers\states.