I'm doing a wpf program, and I did a custom style button:
<Style x:Key="ButtonMio" TargetType="{x:Type Button}">
<Setter Property="Padding" Value="1"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="border" Background="{TemplateBinding Background}">
<ContentPresenter Name="content" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF3EC8C6" />
<Setter Property="Foreground" Value="Transparent"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Well, the button ha an image as content (so it's smaller than the real button). Since the background is transparent, i wrote this in mouse over trigger:
<Setter Property="Background" Value="#FF3EC8C6" />
And it works. But only before the click. Afterclick there is no more background. Even clicking other buttons and making the first one to lose the focus (i think) the background still doesn't appears.
I tiried changing the "IsPressed" and "IsFocused", but in first case, the background doesn't disappear afterclick, and in second, nothing couse I don't use tab to focus elements.
Really sorry for my english. Hope everything is clear. Thanks!
The order in which the triggers are declared is the problem .
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF3EC8C6" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
The IsMouseOver Occurs by right after it the IsFocused kicks in and makes the background transparent.
Try it like this :
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="#FF3EC8C6" /> </Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
Related
I want to change the color of my button permanently, if the user clicked a button. How do I achieve that in XAML?
The trigger I have right now won't work, because they are only temporary, not overriding default values.
Here my button template:
<Style TargetType="{x:Type Button}" x:Key="ButtonStyleNavigation">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="#FF365B74" />
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="FontFamily" Value="Arial" />
<!-- <Setter Property="BorderThickness" Value="2"/>-->
<!-- <Setter Property="BorderBrush" Value="Yellow"/>-->
<Setter Property="FontSize" Value="15" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="10" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,5,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.3"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Yellow" />
<Setter Property="Background" Value="#FF658EAA"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Yellow" />
<Setter Property="Foreground" Value="#FF658EAA" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
SOLUTION:
So, I was able to get what I needed with the use of a ToggleButton. I've bound for each button one property to their IsChecked function.
In my ViewModel I change the checked-state accordingly to my desire. (mentioned in the comments)
Here is my new ToggleButton template:
<Style TargetType="{x:Type ToggleButton}" x:Key="ButtonStyleNavigation">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="#FF365B74" />
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="FontSize" Value="15" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border CornerRadius="10" Background="{TemplateBinding Background}" Height="19">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,5,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Foreground" Value="Yellow" />
<Setter Property="Background" Value="#FF658EAA"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="#FF365B74" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Yellow" />
<Setter Property="Background" Value="#FF658EAA"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Yellow" />
<Setter Property="Foreground" Value="#FF658EAA" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Sounds like you want a ToggleButton. They have a bool property called "IsChecked" that changes each time you click the button.
Taking the style you provided and changing it like so should achieve what you want.
<Style TargetType="{x:Type ToggleButton}" x:Key="ButtonStyleNavigation">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="#FF365B74" />
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="FontSize" Value="15" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border CornerRadius="10" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,5,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.3"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="Yellow" />
<Setter Property="Foreground" Value="#FF658EAA" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="#FF658EAA" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have removed the IsMouseOver trigger as it conflicts with the IsChecked triggers.
When you say you permanently i presume this is what you mean. If you wish for the button to remain the same colour after a user clicks on the button again, you will have to deal with click events and check for number of clicks on the button.
EDIT:
As per your comment, if you want to have only one button enabled at time, look into using radio buttons instead.
Here is a tutorial on getting multiple radio buttons set up.
Check out this answer on how to style them to look like normal buttons.
You can then use the triggers in a similar fashion to check for enum values in your view model.
Here is a pure xaml answer, using a ControlTemplate as requested, taking your original question and just changing the <ControlTemplate.Triggers> section:
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Foreground).(SolidColorBrush.Color)" To="Yellow" Duration="0"/>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" To="#FF658EAA" Duration="0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
In your original question you had (perhaps unintentionally) triggered from the mouse over event, in which case change here the RoutedEvent accordingly.
NB. You may be able to find an alternative to ColourAnimation with a zero duration, but I thought I'd post this as it at least gives you something to work with.
I am trying to change the background color when button gets click/focused but there is not any change occurring.
<Style x:Key="btnInputForm" TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="22"/>
<Setter Property="Background" Value="#2f772b"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Width" Value="120"/>
<Setter Property="Height" Value="23"/>
<Setter Property="Button.RenderTransformOrigin" Value=".5,.5"/>
<Setter Property="TextElement.FontSize" Value="14" />
<Setter Property="TextElement.FontFamily" Value="Calibri" />
<Setter Property="Control.BorderBrush" Value="#085b09" />
<Setter Property="Control.BorderThickness" Value="1,1,1,1" />
<Setter Property="Margin" Value="3,10,3,3" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="VerticalAlignment" Value="Bottom" />
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Yellow"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="Black"/>
<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>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Yellow"/>
</Trigger>
</Style.Triggers>
</Style>
And the button:
<Button Content="Click Me" Height="30" Width="100"></Button>
I have a Style-Template for my buttons in my app, that looks like this:
<Style TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border">
<ContentPresenter RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter TargetName="Border" Property="BorderBrush" Value="#ffffff" />
</Trigger>
<Trigger Property="IsDefaulted" Value="true">
<Setter TargetName="Border" Property="BorderBrush" Value="#ffffff" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="Transparent" />
<Setter TargetName="Border" Property="BorderBrush" Value="#ffffff" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="Transparent" />
<Setter TargetName="Border" Property="BorderBrush" Value="#ffffff" />
<Setter Property="Foreground" Value="Transparent"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now I wanted to put a MouseEnter and a MouseLeave Event in some of my buttons and change their background, etc. on the fly. If I disable the Style, everything works fine as expected (except, that the buttons get the border and the blue background of the standard style).Now my question would be: "How can I change the style to a borderless, transparent button without blue background on MouseOver and get the MouseEnter and MouseLeave to fire, so I can set the background programmatically?
you should add extra styles for the buttons that you want to react differently than the rest, then use the triggers like in your pasted code to change backgrounds.
<Style x:Key="diffrentButton" TargetType="{x:Type Button}">
...
I have a ToggleButton custom control which changes the text and size when toggled. I can change/set fonts and change the background/foreground properties and it works fine.
But as soon as I set the FontSize property of the ContentPresenter the text in the button gets misaligned! Specifically the vertical position seems to be off (Moves way down in the button)
I can't figure out what's causing this. If I don't set the fontsize everything works as intended. Here is my button.
<Style x:Key="PlusSelectedToggleButton" TargetType="{x:Type ToggleButton}" BasedOn="{x:Null}">
<Setter Property="Background" Value="#FF3498DB" />
<Setter Property="BorderBrush" Value="DarkGray" />
<Setter Property="Padding" Value="1"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="Border" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" CornerRadius="4">
<ContentPresenter x:Name="ContentPresenter" RecognizesAccessKey="True"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" Value="Black" TargetName="Border" />
<Setter Property="BorderBrush" Value="White" TargetName="Border" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="TextBlock.Foreground" Value="Black" TargetName="ContentPresenter" />
</Trigger>
<Trigger Property="IsEnabled" Value="true">
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value="Selected" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="TextBlock.Foreground" Value="DarkGray" TargetName="ContentPresenter" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Width" Value="75" TargetName="Border" />
<Setter Property="Height" Value="40" TargetName="Border" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Content" Value="+"/>
<Setter Property="TextBlock.FontSize" Value="50" TargetName="ContentPresenter"/>
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Background" Value="#FF3498DB" />
<Setter Property="Width" Value="40"/>
<Setter Property="Height" Value="40"/>
<Setter Property="TextBlock.Foreground" Value="White" TargetName="ContentPresenter" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Update: I got it to work but I still don't fully understand why I have to do this.
<Trigger Property="IsChecked" Value="False">
<Setter Property="Content" Value="+"/>
<Setter Property="TextBlock.Foreground" Value="White" TargetName="ContentPresenter" />
<Setter Property="TextBlock.FontSize" Value="27" TargetName="ContentPresenter"/>
<Setter Property="TextBlock.FontWeight" Value="Thin"></Setter>
<Setter Property="TextBlock.Height" Value="40" TargetName="ContentPresenter"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Background" Value="#FF3498DB" />
<Setter Property="Width" Value="35"/>
<Setter Property="Height" Value="35"/>
</Trigger>
I had to set the TextBlock.Height property to a much larger value (even larger then button height) to get the text to center vertically. Horizontally it stays at the same place. I'm not sure why it behaves like this.
I am new to Styles and not sure on the best way to create a Button style to change the Foreground of IsMouseOver and IsPressed. I used a Border for a template because it has a CornerRadius and background and border properties. But Border does not have a Foreground property. Using Button as the template doesn't work well since the default look isn't being overridden.
What is a better way to style a Button template with Foreground behavior? Maybe using a label inside the border?
Here is the App.xaml:
<Application.Resources>
<Style TargetType="Button" x:Key="MyButton">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="34"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="shortcutbutton"
BorderThickness="1"
BorderBrush="Black"
Background="Gray">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="#FFDADADA" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="#EEEEEE" />
<!--<Setter TargetName="Border" Property="Foreground" Value="Black" />-->
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="DarkGray" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="Black" />
<!--<Setter TargetName="Border" Property="Foreground" Value="Red" />-->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
And the xaml:
<StackPanel HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="100">
<Button Content="Button" Height="41" Style="{DynamicResource MyButton}"/>
</StackPanel>
You need to move your Triggers from the ControlTemplate to the Style. Something like this:
<Style TargetType="Button">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="34"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="shortcutbutton"
BorderThickness="1"
BorderBrush="Black"
Background="Gray">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="#FFDADADA" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Foreground" Value="DarkGray" />
</Trigger>
</Style.Triggers>
</Style>
What you can do is set attached property of TextElement on the Border and like that every text element within your Border will be of that colour:
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="#FFDADADA" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="#EEEEEE" />
<Setter TargetName="shortcutbutton" Property="TextElement.Foreground" Value="White"/>
</Trigger>
...
</ControlTemplate.Triggers>