Change the Button contents in XAML on trigger - c#

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 :)

Related

Change BorderBrush when button IsPressed

I'm creating a WPF application for a touchscreen.
There should be a button on the screen with an Icon (image).
The code below shows how the button should look like.
So far so good..
What I would like to achieve is that when you press the button, the first BorderBrush color should change from “#0070b8” to “#00395c” and the second BorderBrush color should change from “#e3e3e3” to “#727272”.
Could someone please help me how to achieve this?
<Button Width="64" Height="64" Grid.Row="1" Margin="1,1" HorizontalAlignment="Left" VerticalAlignment="Top">
<Image Source="Resources\Home_Icon_2.bmp" Width="54" Height="54"></Image>
<Button.Style>
<Style TargetType="{x:Type Button}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border CornerRadius="6" Background="{TemplateBinding Background}" Name="button" Width="64">
<Grid>
<Border BorderThickness="0,0,2,2" BorderBrush="#0070b8" CornerRadius="{Binding ElementName=button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="1" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<Border BorderThickness="2,2,0,0" BorderBrush="#e3e3e3" Opacity="0.5" CornerRadius="{Binding ElementName=button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="1" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<ContentPresenter TextBlock.FontSize="{TemplateBinding FontSize}" TextBlock.FontFamily="{TemplateBinding FontFamily}" TextBlock.Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"></ContentPresenter>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="button" Property="Background" Value="#e3e3e3" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="#c6c3c6" />
</Style>
</Button.Style>
</Button>
You could always set the brush color in your click event:
private void btnYourButton_Click(object sender, RoutedEventArgs e)
{
btnYourButton.BorderBrush = (Brush)new BrushConverter().ConvertFrom("#00395c");
}
This would be one solution. Note that we've assigned our brushes to separate resources so that we don't have magic numbers in our style. This is ideal for when you need to use the same colour scheme across multiple controls, and saves a lot of time when you want to change said colour scheme.
<Style x:Key="AdtakrButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="ButtonBorder" CornerRadius="5" BorderThickness="{DynamicResource AdtakrButtonBorderThickness}" BorderBrush="{DynamicResource AdtakrBlack}" Background="{DynamicResource AdtakrWhite}" Margin="{DynamicResource ButtonMargin}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="6,0,6,0" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource AdtakrGrey2}"/>
<Setter Property="BorderBrush" Value="{DynamicResource AdtakrGrey2}" TargetName="ButtonBorder"/>
<Setter Property="Background" Value="{DynamicResource AdtakrGrey1}" TargetName="ButtonBorder"/>
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource AdtakrGrey2}" TargetName="ButtonBorder"/>
<Setter Property="BorderBrush" Value="{DynamicResource AdtakrGrey2}" TargetName="ButtonBorder"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{DynamicResource AdtakrLightBlue}" TargetName="ButtonBorder"/>
<Setter Property="BorderBrush" Value="{DynamicResource AdtakrLightBlue}" TargetName="ButtonBorder"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="{DynamicResource AdtakrDefFontSize}"/>
<Setter Property="MinWidth" Value="90"/>
<Setter Property="Height" Value="40"/>
<Setter Property="ToolTipService.ShowOnDisabled" Value="True"/>
</Style>
If you need to have it change between more than 1 colour, then your best bet is to have a command on your databound VM and the command changes a colour property that the button also binds to. Alternatively, if it's supposed to reflect 3 states, using a toggle button with the three state option is probably your better bet, as then you can set triggers against the IsChecked property of the button.
Found the solution!
By giving the borders a name and then they are accessible in the Trigger Property
<Button Width="64" Height="64" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top">
<Image Source="Images\Home_Icon_2.png" Width="54" Height="54"></Image>
<Button.Style>
<Style TargetType="{x:Type Button}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border x:Name="button" CornerRadius="6" Background="{TemplateBinding Background}" Width="64">
<Grid>
<Border x:Name="border1" BorderThickness="0,0,2,2" BorderBrush="#0070b8" CornerRadius="{Binding ElementName=button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="1" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<Border x:Name="border2" BorderThickness="2,2,0,0" BorderBrush="#e3e3e3" Opacity="0.5" CornerRadius="{Binding ElementName=button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="1" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<ContentPresenter TextBlock.FontSize="{TemplateBinding FontSize}" TextBlock.FontFamily="{TemplateBinding FontFamily}" TextBlock.Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"></ContentPresenter>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="button" Property="Background" Value="#e3e3e3" />
<Setter TargetName="border1" Property="BorderBrush" Value="#00395c" />
<Setter TargetName="border2" Property="BorderBrush" Value="#727272" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="#c6c3c6" />
</Style>
</Button.Style>
</Button>

TextBox SelectionStart is always 0 with custom style

I have a TextBox input field with a custom style:
<TextBox Style="{StaticResource SettingsTextBoxHint}" KeyDown="textBoxInput_KeyDown" PreviewKeyDown="textBoxInput_PreviewKeyDown" Name="TextBoxInput" Text="{Binding TextBoxInput, Mode=TwoWay}" Tag="{lex:LocText TypeAMessageHere}" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" FontSize="14" HorizontalAlignment="Stretch" VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0" Margin="0,0,33,0"/>
To which I added the custom style:
<Style TargetType="{x:Type TextBox}" x:Key="SettingsTextBoxHint" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
BorderThickness="{TemplateBinding BorderThickness}"
Background="White"
Padding="1,2,5,2"
BorderBrush="{StaticResource PrimaryColor}"
ToolTip="{TemplateBinding ToolTip}">
<Grid>
<TextBox Text="{Binding Path=Text,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
x:Name="textSource"
Background="Transparent"
BorderBrush="Transparent"
TextWrapping="{TemplateBinding TextWrapping}"
Panel.ZIndex="2"
FontSize="12">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
Background="Transparent"
BorderBrush="Transparent"
CornerRadius="0">
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
</TextBox>
<TextBox Margin="0,3,0,0" BorderThickness="0" Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontFamily" Value="{StaticResource RobotoRegularFont}" />
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="#cccccc"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="BorderBrush" Value="DarkGray"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="textSource" Property="FocusManager.FocusedElement" Value="{Binding ElementName=textSource}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The point of which is to make the TextBox transparent and to add hint functionality which text is set trough Tag.
Everything works exactly as I want. The problem I have is that I am writing a new functionality in which I need the position of cursor in the TextBox. But SelectionStart or CaretIndex always return 0 value. If I remove my style I get the correct value.
Can anyone tell me what I missed?
The problem is that you are using a TextBox within a TextBox. The user interacts with the inner text box, whose text, caret position, etc. are in no way related to the outer text box.
Let me clean up your style for you:
<Style x:Key="SettingsTextBoxHint"
TargetType="{x:Type TextBox}"
BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="BorderBrush"
Value="{StaticResource PrimaryColor}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Padding="{TemplateBinding Padding}">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" />
<TextBlock x:Name="Hint"
Margin="3,1"
Text="{TemplateBinding Tag}"
FontStyle="Italic"
Foreground="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"
Visibility="Hidden" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="Text" Value="">
<Setter TargetName="Hint" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
To find the cursor position within the TextBox, you can use Mouse.GetPosition(your_text_box). To get the caret position within the text, use the CaretIndex property. Note, however, that CaretIndex is *not* a dependency property, so it does not raise change notifications. Thus, you cannot bind to it and expect the binding target to be updated.

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"

Background does not change of button C# WPF

I am trying to change style on mouseover.
My Code is:
<Button Name="register" Content="Register" Margin="15,410,20,0" Padding="6" FontSize="18" VerticalAlignment="Top" Background="#FF0090D6" BorderBrush="#FF0090D6" Foreground="White">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
But the Background is the same default thing. But when i change property to BorderThickness then it works.
What am i doing wrong?
In the default template of button, there is trigger in ControlTemplate which set Background of button to #FFBEE6FD and since control template triggers have higher precedence compared to Style triggers that's why your trigger never works.
For that to achieve you have to override default template of button and remove that trigger from it so that your style trigger gets applied.
Here is the default template with that specific trigger commented out. In case you want to override BorderBrush as well, get rid of it as well from the template.
<ControlTemplate x:Key="DefaultTemplateOfButton" TargetType="ButtonBase">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
Name="border"
SnapsToDevicePixels="True">
<ContentPresenter RecognizesAccessKey="True"
Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
Name="contentPresenter"
Margin="{TemplateBinding Control.Padding}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
Focusable="False" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsDefaulted" Value="True">
<Setter Property="Border.BorderBrush" TargetName="border">
<Setter.Value>
<DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<!--<Setter Property="Panel.Background" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FFBEE6FD</SolidColorBrush>
</Setter.Value>
</Setter>-->
<Setter Property="Border.BorderBrush" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FF3C7FB1</SolidColorBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="ButtonBase.IsPressed" Value="True">
<Setter Property="Panel.Background" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FFC4E5F6</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="Border.BorderBrush" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FF2C628B</SolidColorBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Panel.Background" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FFBCDDEE</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="Border.BorderBrush" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FF245A83</SolidColorBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="Panel.Background" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FFF4F4F4</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="Border.BorderBrush" TargetName="border">
<Setter.Value>
<SolidColorBrush>#FFADB2B5</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter">
<Setter.Value>
<SolidColorBrush>#FF838383</SolidColorBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
How to set the control template to button?
Define the template somewhere under resource section of parent panel or UserControl and can be applied via StaticResource:
<Grid>
<Grid.Resources>
<ControlTemplate x:Key="MyTemplate"
TargetType="ButtonBase">
.......
</Grid.Resources>
<Button Name="register" Template="{StaticResource MyTemplate}"...>
</Grid>
Edit: As Rohit pointed out in the comments,
This won't work on Windows 8 because of some changes in PresentationFramework where default template of button is declared. ... In Windows 7 default template of button doesn't have that ControlTemplate trigger. That's why your posted code works fine on Windows7 but it won't work on Windows 8 and higher.
Rohit's answer about DependencyProperty Precedence being the cause is correct, but there's a much simpler way of fixing it than overwriting the Button's Template.
If you review the DependencyProperty Precedence List, you'll notice that properties set in the <Tag> have a higher precedence than Triggered properties, which is why your button will always use the background you have defined in your <Button> tag.
If you move the Background property to the <Style> itself, then triggered property will work since Triggered properties take precedence over properties defined in a Style.
<Button Name="register" Content="Register" ...>
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="#FF0090D6" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
You have to override the default template for achieve this.
<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="{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="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Hope this helps.
<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="{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="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Above code perfectly works,
Even with this user can change the background color of button in runtime/codebehind

C# WPF ToggleButton Changing more than one property in a trigger?

I have a togglebutton and when it is clicked I simply want to change the background and the content. The content changes correctly, but the background changes, but instead of my specified background value, it is a default (?) blue-ish. In previous struggles I could get the background to change, but not the content. That was done differently, though, w/ a datatrigger instead of the method below.
I'm using C# WPF and MVVM and could bind the content to another property and when the binded ischecked property is changed, I could change the property in the viewmodel, but I was hoping not to have to do that. Maybe it's the correct way?
Here's my code that 1/2 works:
<ToggleButton Name="Axis3AbsIncButton"
IsChecked="{Binding Path=UserControlOneStatic.MotionParameters.Axis3AbsorIncOption, Source={StaticResource Locator}}">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="ToggleButton.Background" Value="Goldenrod"/>
<Setter Property="ToggleButton.Content"
Value="ABS" />
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="ToggleButton.Background"
Value="Green" />
<Setter Property="ToggleButton.Content"
Value="Inc" />
</Trigger>
</Style.Triggers>
</Style >
</ToggleButton.Style>
</ToggleButton>
This is very close, but I have lost the border of the togglebutton:
<ToggleButton Name="Axis3AbsIncButton"
Grid.Row="2"
Grid.Column="13"
Grid.ColumnSpan="2"
Grid.RowSpan="1"
Focusable="True"
IsChecked="{Binding Path=UserControlOneStatic.MotionParameters.Axis3AbsorIncOption, Source={StaticResource Locator}}">
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border CornerRadius="3" BorderThickness="1" Background="{TemplateBinding Background}">
<ContentPresenter Margin="3"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="False">
<Setter Property="Background"
Value="Goldenrod">
</Setter>
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter Property="Background"
Value="Blue" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="ToggleButton.Content"
Value="ABS" />
<Style.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter Property="ToggleButton.Content"
Value="Inc" />
</Trigger>
</Style.Triggers>
</Style >
</ToggleButton.Style>
</ToggleButton>
Your XAML code is correct. When you click ToggleButton, background color changed to green. But it's changing when you move mouse from button. When mouse coursor is over ToggleButton, it has blue color.
Edit:
Try this:
<ToggleButton Name="Axis3AbsIncButton"
Grid.Row="2"
Grid.Column="13"
Grid.ColumnSpan="2"
Grid.RowSpan="1"
Focusable="True"
IsChecked="{Binding Path=UserControlOneStatic.MotionParameters.Axis3AbsorIncOption, Source={StaticResource Locator}}">
<ToggleButton.Template>
<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="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>
</ToggleButton.Template>
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="ToggleButton.Background" Value="Goldenrod"/>
<Setter Property="ToggleButton.Content"
Value="ABS" />
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="ToggleButton.Background"
Value="Green" />
<Setter Property="ToggleButton.Content"
Value="Inc" />
</Trigger>
</Style.Triggers>
</Style >
</ToggleButton.Style>
</ToggleButton>

Categories