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();
}
}
Related
I made a simple style for the hyperlinks that target buttons:
<Style x:Key="Hyperlink" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="{StaticResource ForegroundDarkBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<TextBlock x:Name="innerText" Text="{TemplateBinding Content}" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{StaticResource AppDarkBlueBrush}" />
<Setter TargetName="innerText" Property="TextDecorations" Value="Underline" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
My problem is that, when applied to the button control that has set some properties like FontSize, FontWeight, FontFamily, they are simply ignored and do not work:
<Button
Command="{Binding OpenCommand}"
Content="Open"
FontSize="20"
Style="{StaticResource Hyperlink}" />
How can I make a TextBlock in my style template inherit such properties?
edit
Forgot my mention that properties like FontSize actually do work but only in the design mode.
You can indicate that you want your textblock to "inherit" some properties from the Button like this :
<Style x:Key="Hyperlink" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Foreground" Value="{StaticResource ForegroundDarkBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<TextBlock
x:Name="innerText"
Text="{TemplateBinding Content}"
FontSize={TemplateBinding FontSize}
FontWeight={TemplateBinding FontWeight}
FontFamily={TemplateBinding FontFamily}
/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{StaticResource AppDarkBlueBrush}" />
<Setter TargetName="innerText" Property="TextDecorations" Value="Underline" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
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 simply created 3 borders in a StackPanel like this:
<StackPanel Orientation="Horizontal" >
<Border Width="100" Height="30" Background="Red" BorderBrush="DarkRed" BorderThickness="4" Margin="0" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Panel.ZIndex" Value="0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
<Border Width="100" Height="30" Background="Blue" BorderBrush="DarkBlue" BorderThickness="4" Margin="-10,0,0,0" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Panel.ZIndex" Value="0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
<Border Width="100" Height="30" Background="Green" BorderBrush="DarkGreen" BorderThickness="4" Margin="-10,0,0,0" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Panel.ZIndex" Value="0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</StackPanel>
the xaml will layout 3 different colors borders:
When i mouse over the blue one, it'll on the top of others:
But when I move all of these into a ItemsControl, mouse on blue border no longer on the top of others, it just stay it's original ZIndex.
<DataTemplate x:Key="BorderTemplate">
<Border Width="100" Height="30" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background" Value="Red"/>
<Setter Property="BorderBrush" Value="DarkRed"/>
<Setter Property="BorderThickness" Value="4"/>
<Setter Property="Panel.ZIndex" Value="0"/>
<Setter Property="Margin" Value="0,0,0,0"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Type}" Value="2">
<Setter Property="Background" Value="Blue"/>
<Setter Property="BorderBrush" Value="DarkBlue"/>
<Setter Property="BorderThickness" Value="4"/>
<Setter Property="Panel.ZIndex" Value="0"/>
<Setter Property="Margin" Value="-10,0,0,0"/>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="3">
<Setter Property="Background" Value="Green"/>
<Setter Property="BorderBrush" Value="DarkGreen"/>
<Setter Property="BorderThickness" Value="4"/>
<Setter Property="Panel.ZIndex" Value="0"/>
<Setter Property="Margin" Value="-10,0,0,0"/>
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="1"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</DataTemplate>
<ItemsControl ItemsSource="{Binding Borders}" ItemTemplate="{StaticResource BorderTemplate}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate >
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
So why Panel.ZIndex worked in StackPanel but not work in ItemsControl->StackPanel?
ZIndex is by no means limited to canvas, so let's not push that idea off on other readers Maximus. However, since you're now loading your stuff as an ItemTemplate, using just a ContentPresenter, so you're basically sandboxing your object in a panel not associated to the overall DOM. Try instead to throw your influence at the ContentPresenter as the object being your container instead of disassociated children nested in it individually. Something like this (after you pull the same triggers off each Border of course).
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
</Trigger>
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
Hope this helps. Cheers.
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>
I have create a style for a button like this
<Style TargetType="{x:Type Button}" x:Key="BoutonRessources">
<Setter Property="Width" Value="18" />
<Setter Property="Margin" Value="-1,0,-2,0" />
<Setter Property="ToolTip" Value="Clear" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="BoutonToolbarSelected.png"/>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="22"/>
<Setter Property="Width" Value="32"/>
</Trigger>
</Style.Triggers>
</Style>
My button appear on my screen but when the mouse is over the button, it don't show my "BoutonToolbarSelected.png". Do you know why ?
Here is how i call my button :
<Button Style="{StaticResource BoutonRessources}" >
<Image Source= "xRtDiva_XWPF_TBR_PREMIER.PNG_IMAGES.png" Height="18"/>
</Button>
Thanks a lot :)
Because you set <Image Source= "xRtDiva_XWPF_TBR_PREMIER.PNG_IMAGES.png" Height="18"/> as Content of your button, the background will hide behind it.
You could change your trigger to:
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="BoutonToolbarSelected.png"/>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="22"/>
<Setter Property="Width" Value="32"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="xRtDiva_XWPF_TBR_PREMIER.PNG_IMAGES.png"/>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="18"/>
</Trigger>
</Style.Triggers>