Buttons' background being flickering or disappearing on Mouse Over - c#

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>

Related

WPF XAML Styles not applying properly (.NET 5)

I'm trying to apply 2 custom styles to 2 Buttons on a UserControl.
Here I have the Styles defined in a Buttons.xaml ResourceDictionary which is properly registered as a ResourceDictionary in App.xaml.
<!-- Contained button -->
<Style TargetType="{x:Type Button}" x:Key="MaterialContainedButton">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Background" Value="{StaticResource PrimaryBrush}" />
<Setter Property="Foreground" Value="{StaticResource ForegroundLightBrush}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Padding" Value="8" />
<Setter Property="MinWidth" Value="64" />
<Setter Property="Height" Value="36" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
CornerRadius="3">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Medium" Text="{TemplateBinding Content}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource PrimaryLightBrush}" />
</Trigger>
</Style.Triggers>
</Style>
<!-- Outlined button -->
<Style TargetType="{x:Type Button}" x:Key="MaterialOutlinedButton">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{StaticResource PrimaryBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource PrimaryBrush}" />
<Setter Property="Padding" Value="8" />
<Setter Property="MinWidth" Value="64" />
<Setter Property="Height" Value="36" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderThickness="1"
CornerRadius="3">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Medium" Text="{TemplateBinding Content}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource PrimaryBrush}" />
<Setter Property="Foreground" Value="{StaticResource ForegroundLightBrush}" />
</Trigger>
</Style.Triggers>
</Style>
And the two Buttons on my UserControl are defined as follows:
<StackPanel
Grid.Row="2"
Grid.ColumnSpan="2"
Orientation="Horizontal"
HorizontalAlignment="Right"
VerticalAlignment="Bottom">
<Button
Style="{StaticResource MaterialOutlinedButton}"
Content="CANCEL"
Margin="10"
/>
<Button
Style="{StaticResource MaterialContainedButton}"
Content="SAVE"
Margin="10"
/>
</StackPanel>
I have 2 problems with this code:
For some reason the BorderThickness Property in the second style doesn't apply to its respective Button.
The Buttons differ in Height although they should have the same Height based on their styles
All other styles in my Buttons.xaml file work just fine, it's just these two that just don't seem to work as they should. If anyone has any idea how to solve this issue I would greatly appreciate it.

Modify Properties inside a Style programmatically

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"

Transparent button background in WPF using style

I've found this topic about setting the border of a button to transparent.
This works fine, but I want to use this for the button background and not the border.
Solution in link which I've put in <Window.Resources>...</Window.Resources>:
<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="Red"/>
</Trigger>
</Style.Triggers>
</Style>
Source: How do you change Background for a Button MouseOver in WPF?
How can edit this code so I can use this to set the background of my button to transparent and not the border of it?
Try this snippet for a transparent button:
<Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0">
<-- PUT BUTTON CONTENT HERE e.g. a Image -->
</Button>
Found the solution for my issue:
Apparently you have to add the triggers within the ControlTemplate under ControlTemplate.Trigger. Andd after you've done that the thing with borders is that you have to set a TargetName in the Border tag and then set the reference (-> TargetName="XXXXX") to the properties which you've named in the border tag.
So:
<Window.Resources>
<Style x:Key="MenuButton" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Height" Value="40" />
<Setter Property="Width" Value="Auto" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Margin" Value="45,0,0,0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Name="MenuBorder" SnapsToDevicePixels="True" BorderBrush="Black" Background="{TemplateBinding Background}" BorderThickness="0,0,0,2" >
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsFocused" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Setter TargetName="MenuBorder" Property="BorderBrush" Value="#FFED6A2B" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Change this line
<Setter Property="Background" Value="Red"/>
to
<Setter Property="Background" Value="Transparent"/>
Use this in C# code
Button btn = new Button() {BorderBrush=System.Windows.Media.Brushes.Transparent,
BorderThickness = new Thickness(0)};
or
yourBtn.BorderBrush=System.Windows.Media.Brushes.Transparent;
yourBtn.BorderThickness =new Thickness(0);

ResourceDictionary Style Triggers not working

from the following Trigger only the Foreground Setter is working. I do not understand why.
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="Foreground" Value="Red"/>
</Trigger>
Thanks for any help.
The reason this doesn't work is because the default Button template uses a ButtonChrome that draws the border and background and handles states like mouseover and disabled depending on the Windows theme (e.g. Windows XP style, Windows 7 style).
In order to allow your triggers to be applied, you will need to define a custom Button template that uses standard stylable WPF elements, like Border, instead of ButtonChrome. Here's a bare-bones working example:
<Button Content="button">
<Button.Style>
<Style TargetType="Button">
<Setter Property="BorderThickness" Value="3" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Property=Background}"
BorderBrush="{TemplateBinding Property=BorderBrush}"
BorderThickness="{TemplateBinding Property=BorderThickness}">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
<Setter Property="BorderBrush" Value="Green" />
<Setter Property="Foreground" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Button in WPF has a default control template. The correct way to override the Button's default behavior is by overriding default control template. This can be done with something similar to below:
<Button Width="100" Height="50" Content="Click Me!">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="bdr_main" CornerRadius="20" Margin="4" BorderThickness="1" BorderBrush="Black" Background="LightGray">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Margin="8,6,8,6" ContentSource="Content" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bdr_main" Property="Background" Value="LightGreen"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="bdr_main" Property="Background" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
Found # http://harishasanblog.blogspot.com/2011/02/ismouseover-trigger-not-working-in-wpf.html
Hope it helps!
Try using the trigger on the controltemplate.
<ResourceDictionary>
<Style x:Key="TestButton" TargetType="Button">
<Setter Property="Height" Value="30" />
<Setter Property="Width" Value="30" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Green" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Purple" />
</Trigger>
</ControlTemplate.Triggers>
<Grid>
<Rectangle Fill="{TemplateBinding Foreground}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

Change the Button contents in XAML on trigger

I'm trying to make a template that will change a Button's background as well as the color of it's TextBlock. I tried the following XAML in my template, but it just makes the button dissapear on mouseover. Is there any way to change the properties of a buttons contents on triggers?
<ControlTemplate TargetType="{x:Type Button}">
<Border
x:Name="Border"
CornerRadius="0"
BorderThickness="0"
Background="{x:Null}"
BorderBrush="#FF404040" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="White" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="TextBlock">
<TextBlock Foreground="Blue" />
</DataTemplate>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
Style:
<Style TargetType="{x:Type Button}" x:Key="MyButton">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border"
CornerRadius="0"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
TextBlock.Foreground="{TemplateBinding Foreground}"
BorderBrush="#FF404040">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="White" />
<Setter TargetName="Border" Property="TextBlock.Foreground" Value="Blue" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage:
<Button Width="100" Height="50" Content="Lalala" Style="{StaticResource MyButton}" Background="Brown" Foreground="Green" BorderThickness="2"></Button>
You're missing the ContentPresenter, responsible for visualizing the Content property of the Button.
To set the foreground you can use TextBlock.Foreground attached property.
Control Styles and Templates has always been very usefull to me :)

Categories