I have a styled button as follow :
<Style x:Key="btnDefaultOperationImage" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="brdMenu"
BorderThickness="0"
Padding="4,2"
BorderBrush="White"
Background="#20000000">
<StackPanel>
<ContentPresenter x:Name="ButtonContentPresenter" VerticalAlignment="Center" HorizontalAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Center" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="/Images/Icons/CourtHearing.png" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=Name}" Value="btnCases">
<Setter Property="Source" Value="/Images/Icons/Cases.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="brdMenu" Property="BorderBrush" Value="#F2826A"/>
<Setter TargetName="brdMenu" Property="Background" Value="#30000000"/>
<Setter TargetName="brdMenu" Property="TextElement.FontSize" Value="25"/>
<Setter TargetName="brdMenu" Property="TextElement.Foreground" Value="AntiqueWhite"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="brdMenu" Property="BorderBrush" Value="OrangeRed" />
<Setter TargetName="brdMenu" Property="Background" Value="White" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<!--<Setter TargetName="brdMenu" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />-->
<Setter TargetName="brdMenu" Property="Background" Value="#f9f9f9" />
<Setter TargetName="brdMenu" Property="Opacity" Value="0.3" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I want to use this style on many buttons, but each button will have a different image according to it name, for example :
The Button Name="btnCases" the ImageSource="..\..\Cases.png"
The Button Name="btnActors" the ImageSource="..\..\Actors.png"
I am wondering if it 's possible to use DataTrigger to solve this issue, i tried
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=Name}" Value="btnCases">
But it doesn't work.
I think you're asking for something like this. What you need to do is bind your image source to a property on each button. I've used the tag property in this example, but you could use anything - attached property, ViewModel property etc..
<Window.Resources>
<Style x:Key="btnDefaultOperationImage" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="brdMenu"
BorderThickness="0"
Padding="4,2"
BorderBrush="White"
Background="#20000000">
<StackPanel>
<ContentPresenter x:Name="ButtonContentPresenter" VerticalAlignment="Center" HorizontalAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Center" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="{Binding Tag, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" />
</Style>
</Image.Style>
</Image>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="brdMenu" Property="BorderBrush" Value="#F2826A"/>
<Setter TargetName="brdMenu" Property="Background" Value="#30000000"/>
<Setter TargetName="brdMenu" Property="TextElement.FontSize" Value="25"/>
<Setter TargetName="brdMenu" Property="TextElement.Foreground" Value="AntiqueWhite"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="brdMenu" Property="BorderBrush" Value="OrangeRed" />
<Setter TargetName="brdMenu" Property="Background" Value="White" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<!--<Setter TargetName="brdMenu" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />-->
<Setter TargetName="brdMenu" Property="Background" Value="#f9f9f9" />
<Setter TargetName="brdMenu" Property="Opacity" Value="0.3" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button Style="{StaticResource btnDefaultOperationImage}" Tag="..\image1.png"/>
<Button Style="{StaticResource btnDefaultOperationImage}" Tag="..\image2.png"/>
</StackPanel>
</Grid>
You can also use Converter
Assuming:
1) Every button is prepend with Btn
2) image is of only one format
<Image Source="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Button}},Path=Name,Converter=
{StaticResource NameToPathConverter}}"/>
then your button will look like:
<Button Name="BtnDestinationPin" Style="{StaticResource btnDefaultOperationImage}" />
Define Converter as a resource:
<local:NameToPathConverter x:Key="NameToPathConverter"/>
Code:
public class NameToPathConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string imageName = value.ToString().Substring(3);
return new BitmapImage(new Uri("pack://application:,,,/YourNamespace;component/Images/" + imageName + ".png"));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
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>
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'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
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.