WPF Button XAML Template - c#

I use a template for my buttons. Now I got to a point where I want to change the template on runtime. But that doesn't work with this template.
The template looks like this:
<Application.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border" Background="Transparent">
<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>
</Application.Resources>
I used it on different windows, therefore as application resource.
How do I access this template and change it for only some buttons?
I thought about creating different templates. But how do I create one where I can change things like Background, etc. on runtime?

If you give an x:key to your resource, you should be able to do something like this:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyProject.Styles;component/ButtonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Then Just use :
<Button>
<Button.Style>
<Style BasedOn="{StaticResource StyleFromButtonStyles}" TargetType="Button">
And override with Style.Setter the property that you want to change

Related

WPF Override a trigger from a button style

I have below button style in window resources:
<Style x:Key="MyStyle" TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0 0 0 3"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Orange" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="BorderBrush" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
This style is shared by two wpf buttons. But there is a button I want to show a custom color when it is pressed, the color will be green.
So in this special button I would like to override the value specified for borderbrush property in the trigger, instead of Red I would like Green.
How to do this?
You could set the BorderBrush property using a {DynamicResource} that you can override:
<SolidColorBrush x:Key="pressed" Color="Red" />
<Style x:Key="MyStyle" TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0 0 0 3"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Orange" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="BorderBrush" Value="{DynamicResource pressed}" />
</Trigger>
</Style.Triggers>
</Style>
...
<Button Content="Red" Style="{StaticResource MyStyle}" />
<Button Content="Green" Style="{StaticResource MyStyle}">
<Button.Resources>
<SolidColorBrush x:Key="pressed" Color="Green" />
</Button.Resources>
</Button>
Or you could create another Style that overrides the entire trigger:
<Button Content="Green">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource MyStyle}">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="Green" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

Wpf Button backround color change when get focused

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>

How to override a datagrid style

I have a styled window and I want to override a datagrid style to ALL datagrids in my application
<Window.Resources>
<Style x:Name="dtgStyle" TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Blue" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="White" />
</Style>
</Window.Resources>
I thougth this had to work but I have to apply
Style s = Resources["dtgStyle"] as Style;
mydtg.Style = s;
now I wouldn't like to have to apply that to ALL dtgs.
The best would be to automatically apply it in xaml.
Thanx
---ADD for ASh----
Thank you for your help. The only problem is that when the datagrid loses focus the selected line in the datagrid changes colour as you can see in the following pic (foreground turns to black).
I have tried to add various property but nothing works.
additionally the left border gets bolder (no pun intended) and larger.
Any idea how to fix it?
Thanks
if you need default style for FrameworkElement, declare it without x:Key, only with TargetType.
Both DataGridRow and DataGridCell have IsSelected property. Not enough to change Background only for DataGridRow, it has to be done for DataGridCell as well
<Style TargetType="{x:Type DataGrid}">
<Setter Property="RowStyle" >
<Setter.Value>
<Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="White" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Orange" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
<Setter Property="CellStyle">
<Setter.Value>
<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Orange" />
</Trigger>
<DataTrigger Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Value="False">
<Setter Property="Foreground" Value="White"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>
fix for Foreground was found here: DataGrid's selected row color when inactive (https://stackoverflow.com/a/25204493/1506454)

WPF ButtonStyle and MouseEnter/-Leave-Event

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

prefix "style" does not map to a namespace

I've looked through every answer here on StackOverflow but nothing fixed my problem.. I have following style written in App.xaml for my buttons. And this style is linked to my class in another assembly where data is being taken from.
This WORKS at runtime, but it's giving me a hard time inside designer.
There are no errors in the style itself, the error begings with ControlTemplate.
<Style x:Key="HeaderBTN" TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Width" Value="36" />
<Setter Property="Padding" Value="5" />
<Setter Property="Background" Value="{Binding Path=(style:AppStyle.AccentMain)}" />
<Setter Property="Foreground" Value="{Binding Path=(style:AppStyle.AccentText)}" />
<Setter Property="FontSize" Value="20" />
<Setter Property="FontFamily" Value="Times New Roman" />
<Setter Property="Margin" Value="0" />
<Setter Property="DockPanel.Dock" Value="Right" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="border" BorderThickness="0" CornerRadius="0" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Name="content"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{Binding Path=(style:AppStyle.AccentHover)}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{Binding Path=(style:AppStyle.AccentButtonDown)}" />
<Setter Property="Foreground" Value="{Binding Path=(style:AppStyle.AccentTextDown)}" />
</Trigger>
<Trigger Property="IsDefaulted" Value="True">
<Setter Property="Background" Value="#3b3b3b" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#505050" />
<Setter Property="Foreground" Value="#A7A7A7" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Is there any alternative to this that would leave everything functional? It's important that these resources are dynamic because Users have to be able to change the theme.
Any help is appreciated.
P.S. I use Visual Studio 2013 Professional with Update 5

Categories