Style disabled components in datagrid - c#

I'd like to get rid of the grey-fading out behavior of datagrid cells (Checkboxes, Timepicker, comboboxes etc) when they have been set to disabled.
So this is what I'm trying to do:
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{x:Null}" />
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
But it doesn't work.
Do I need to define the styles individually for the controls that's actually inside the datagridcell (Checkboxes, comboboxes etc)? What's a good way of making this work?

Firstly, the fact is that the property IsEnabled hard-coded in certain control, so setting properties such as Background impossible, because the color hardcoded in the control. For example - Background in: ComboBox, TextBox, etc. Therefore, in such cases, create styles and templates, overriding the default behavior of the control (in our case: IsEnabled=False behavior).
Secondly, what control in the assigned property DataTemplate IsEnabled like this:
<DataGridTemplateColumn x:Name="ComboBoxColumn" Header="ComboBox Header" Width="110">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox IsEnabled="False" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Not to say that DataGridCell will be False, therefore, the trigger will not fire:
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
Hence the conclusion:
Determine the behavior of the control when it is enabled false. Styles for each control can be taken from MSDN.
Example style for CheckBox (link):
<Style x:Key="{x:Type CheckBox}" TargetType="CheckBox">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource CheckBoxFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Border x:Name="Border" Width="13" Height="13" CornerRadius="0" Background="{StaticResource NormalBrush}" BorderThickness="1" BorderBrush="{StaticResource NormalBorderBrush}">
<Path Width="7" Height="7" x:Name="CheckMark" SnapsToDevicePixels="False" Stroke="{StaticResource GlyphBrush}" StrokeThickness="2" Data="M 0 0 L 7 7 M 0 7 L 7 0" />
</Border>
</BulletDecorator.Bullet>
<ContentPresenter Margin="4,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" RecognizesAccessKey="True" />
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="false">
<Setter TargetName="CheckMark" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="{x:Null}">
<Setter TargetName="CheckMark" Property="Data" Value="M 0 7 L 7 0" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DarkBrush}" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}" />
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource PressedBorderBrush}" />
</Trigger>
<!-- Here set the some properties there IsEnabled will be false -->
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="Red" />
<Setter TargetName="Border" Property="BorderBrush" Value="Green" />
<Setter Property="Foreground" Value="Orange"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have defined the attached DependencyProperty for a column that shows whether it is turned off. Thereafter, each control in the template column is referenced like that:
<DataGridTemplateColumn x:Name="CheckBoxColumn" local:MyDependencyClass.IsEnabledColumn="False" Width="110" Header="CheckBox Header">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Content="My CheckBox" IsEnabled="{Binding Source={x:Reference Name=CheckBoxColumn}, Path=(local:MyDependencyClass.IsEnabledColumn)}" IsChecked="False" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Set the property IsEnabledColumn, you can set for those controls that you want to disable (IsEnabled=False).
Listing of MyDependencyClass:
public class MyDependencyClass : DependencyObject
{
public static readonly DependencyProperty IsEnabledColumnProperty;
public static void SetIsEnabledColumn(DependencyObject DepObject, bool value)
{
DepObject.SetValue(IsEnabledColumnProperty, value);
}
public static bool GetIsEnabledColumn(DependencyObject DepObject)
{
return (bool)DepObject.GetValue(IsEnabledColumnProperty);
}
static MyDependencyClass()
{
PropertyMetadata MyPropertyMetadata = new PropertyMetadata(false);
IsEnabledColumnProperty = DependencyProperty.RegisterAttached("IsEnabledColumn",
typeof(bool),
typeof(MyDependencyClass),
MyPropertyMetadata);
}
}
P.S. Don't worry about {x:Reference} warning message, it can be ignored.

Related

WPF TabControl selected item color change from back code

I'm quite new in C# and WPF so please forgive in case of stupid questions :-).
I would like to change dynamically the selected tab color property from the back code.
I've found few solutions but only for static color change.
Dynamic color change of non-selected tab is done. Please see the code:
XAML:
<TabControl x:Name="tabSections" Margin="0,400,0,20" Width="1348" BorderBrush="{x:Null}" FontSize="16" FontWeight="Bold" Visibility="Visible" TabStripPlacement="Top" Cursor="Hand" SelectionChanged="tabSections_SelectionChanged">
<TabControl.Background>
<SolidColorBrush Color="#FF464646" Opacity="1"/>
</TabControl.Background>
<TabItem x:Name="tabSect1" Width="168" Height="30" Header="Section 1">
</TabItem>
<TabItem x:Name="tabSect2" Width="168" Height="30" Header="Section 2">
</TabItem>
<TabItem x:Name="tabSect3" Width="168" Height="30" Header="Section 3">
</TabItem>
<TabItem x:Name="tabSect4" Width="168" Height="30" Header="Section 4">
</TabItem>
<TabItem x:Name="tabSect5" Width="168" Height="30" Header="Section 5">
</TabItem>
<TabItem x:Name="tabSect6" Width="168" Height="30" Header="Section 6">
</TabItem>
<TabItem x:Name="tabSect7" Width="168" Height="30" Header="Section 7">
</TabItem>
<TabItem x:Name="tabSect8" Width="168" Height="30" Header="Section 8">
</TabItem>
</TabControl>
C#:
for (int i = 0; i < SectionCount; i++)
{
if (TabsColors[i])
{
TabBrushes[i] = Brushes.Orange;
}
else
{
TabBrushes[i] = Brushes.LightGreen;
}
}
for (int j = SectionCount; j < 8; j++)
{
TabBrushes[j] = Brushes.DarkGray;
}
tabSect1.Background = TabBrushes[0];
tabSect2.Background = TabBrushes[1];
tabSect3.Background = TabBrushes[2];
tabSect4.Background = TabBrushes[3];
tabSect5.Background = TabBrushes[4];
tabSect6.Background = TabBrushes[5];
tabSect7.Background = TabBrushes[6];
tabSect8.Background = TabBrushes[7];
Thank you for help in advance. Have a nice day.
You can always get the selected item of a Selector control by referencing its SelectedItem property.
To use a Style, simply reference the Brush as a dynamic resource and change it from e.g., your code-behind:
MainWindow.xaml
<Window>
<Window.Resources>
<SolidColorBrush x:Key="SelectedItemBackgroundBrush"
Color="Red" />
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border x:Name="Border"
Margin="0,0,-4,0"
CornerRadius="2,12,0,0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="LightGray" />
</Trigger>
<Trigger Property="IsSelected"
Value="True">
<Setter Property="Panel.ZIndex"
Value="100" />
<Setter Property="Background"
Value="{DynamicResource SelectedItemBackgroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
</Window>
MainWindow.xaml.cs
this.Resources["SelectedItemBackgroundBrush"] = Brushes.GreenYellow;
When you need to acces each element of a collection, you should never access it explicitly. Rather would you iterate over the collection:
for (int tabItemIndex = 0; tabItemIndex < this.tabSections.Items.Count; tabItemindex++)
{
var tabItem = this.tabSections.Items[tabItemIndex] as TabItem;
tabItem.Background = tabItem.IsSelected
? Brushes.Red
: this.TabBrushes[tabItemIndex];
}
// Alternative way to change the color of the selected item
var selectedTabItem = this.tabSections.SelectedItem as TabItem;
selectedTabItem.Background = this.TabBrushes[tabItemIndex];
First I would like to thank you #BionicCode for help.
The mistake I've made from the beginning was the trigger declaration order in XAML.
The below example first declares selected tab property, then enabled tab property which overwrites, so the selected property have no chance to be seen.
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Value="LightGray" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="border" Property="Background" Value="{DynamicResource SelectedItemBackgroundBrush}" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="16"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="border" Property="Background" Value="#FF464646" />
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="FontWeight" Value="UltraLight"/>
</Trigger>
<Trigger Property="IsEnabled" Value="True">
<Setter TargetName="border" Property="Background" Value="{DynamicResource EnabledItemBackgroundBrush}" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontWeight" Value="UltraLight"/>
</Trigger>
</ControlTemplate.Triggers>
The correct order is (selected property after enabled property):
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Value="LightGray" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="border" Property="Background" Value="#FF464646" />
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="FontWeight" Value="UltraLight"/>
</Trigger>
<Trigger Property="IsEnabled" Value="True">
<Setter TargetName="border" Property="Background" Value="{DynamicResource EnabledItemBackgroundBrush}" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontWeight" Value="UltraLight"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="border" Property="Background" Value="{DynamicResource SelectedItemBackgroundBrush}" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="16"/>
</Trigger>
</ControlTemplate.Triggers>
Have a good day!

ListBox ItemTemplate update using ToggleButton and attached Property

I want to implement a ListBox with ToggleButton when I press then the template of ListBox should be updated. The template one will have only icons and one will have both icons and text as shown in the image.
I have created one attached property for this and binded it to the ToggleButton IsChecked property inside control template, but this attached property is not updating and my template is not changing.
First time when I load the application it is working.
<Style x:Key="NavigationListBoxStyle" TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="{StaticResource PrimaryDarkBrush}"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="SelectedIndex" Value="0"/>
<Setter Property="Width" Value="Auto"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border Background="{TemplateBinding Background}"
BorderThickness="0"
Padding="0"
SnapsToDevicePixels="true">
<ScrollViewer Padding="{TemplateBinding Padding}"
Focusable="false">
<StackPanel>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<ToggleButton IsChecked="{Binding local:IsOpenInfo.IsOpen,Mode=TwoWay}" Style="{DynamicResource ToggleButtonstyle}" Foreground="White">
</ToggleButton>
</StackPanel>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate" Value="{DynamicResource NavigationDataTemplate}"/>
<Style.Triggers>
<Trigger Property="local:IsOpenInfo.IsOpen" Value="True">
<Setter Property="ItemTemplate" Value="{DynamicResource NavigationDataTemplate1}"/>
</Trigger>
<Trigger Property="local:IsOpenInfo.IsOpen" Value="False">
<Setter Property="ItemTemplate" Value="{DynamicResource NavigationDataTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ToggleButtonstyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterialDesign x:Name="MenuItemIcon" VerticalAlignment="Center"
HorizontalAlignment="Center" Margin="12" Kind="ArrowBack"/>
<TextBlock Text="Collapse" VerticalAlignment="Center" HorizontalAlignment="Center" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="MenuItemIcon" Property="Kind" Value="ArrowForward"/>
<Setter TargetName="txtBlock" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="false">
<Setter TargetName="MenuItemIcon" Property="Kind" Value="ArrowBack"/>
<Setter TargetName="txtBlock" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="NavigationDataTemplate">
<iconPacks:PackIconMaterialDesign x:Name="MenuItemIcon" VerticalAlignment="Center"
HorizontalAlignment="Center" Margin="12"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding}" Value="Home">
<Setter TargetName="MenuItemIcon" Property="Kind" Value="Home"/>
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="Email">
<Setter TargetName="MenuItemIcon" Property="Kind" Value="Email"/>
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="Cloud">
<Setter TargetName="MenuItemIcon" Property="Kind" Value="Cloud"/>
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="Collapse">
<Setter TargetName="MenuItemIcon" Property="Kind" Value="Mail"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<DataTemplate x:Key="NavigationDataTemplate1">
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconMaterialDesign x:Name="MenuItemIcon" VerticalAlignment="Center"
HorizontalAlignment="Center" Margin="12"/>
<TextBlock Text="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding}" Value="Home">
<Setter TargetName="MenuItemIcon" Property="Kind" Value="Home"/>
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="Email">
<Setter TargetName="MenuItemIcon" Property="Kind" Value="Email"/>
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="Cloud">
<Setter TargetName="MenuItemIcon" Property="Kind" Value="Cloud"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
The attached property class as below:
public class IsOpenInfo
{
public static bool GetIsOpen(DependencyObject obj)
{
return (bool)obj.GetValue(IsOpenProperty);
}
public static void SetIsOpen(DependencyObject obj, bool value)
{
obj.SetValue(IsOpenProperty, value);
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsOpenProperty =
DependencyProperty.RegisterAttached("IsOpen", typeof(bool), typeof(IsOpenInfo), new PropertyMetadata(true));
}
I am clueless why the attached property not updating when IsChecked property is changed and style triggers not working?
Is there any simple way to achieve this?
Anyone guide me to handle this case?
Your style is defined with TargetType set to ListBox, the triggers will resolve the value of your custom local:IsOpenInfo.IsOpen property for the ListBox instance that your style is applied to.
However, the ToggleButton is defined inside the ControlTemplate of the ListBox. Its IsChecked binding will not automatically set the value of the attached property on its templated parent control. It will be set on the ToggleButton itself. So practically, you are setting the value on the ToggleButton, but you are checking it on the ListBox in the style, so you are operating on different values.
You can make it work by explicitly binding to the TemplatedParent, which is a ListBox instance. Both the style and the toggle button will resolve the attached property value for the same ListBox instance.
<ToggleButton IsChecked="{Binding (local:IsOpenInfo.IsOpen), RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Style="{DynamicResource ToggleButtonstyle}"
Foreground="White"/>

How to change ZIndex inside a bound ItemsControl?

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.

Style Basedon not working with checkbox

I have a style defined in a resource dictionary to make my checkbox look like a button:
<Style TargetType="CheckBox" x:Key="CBCheckBoxButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Border Name="BackgroundBorder" Background="Black" CornerRadius="20">
<Grid>
<Rectangle x:Name="UpperRect" Margin="1" Grid.Row="0" RadiusX="20" RadiusY="20" Fill="{StaticResource GrayGradient}"/>
<TextBlock Name="ButtonContent" Text="{TemplateBinding Content}" Margin="3" VerticalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="UpperRect" Property="Fill" Value="{StaticResource LightBlueGradient}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="UpperRect" Property="Fill" Value="{StaticResource BlueGradient}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="BackgroundBorder" Property="Background" Value="DarkGray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Effect" Value="{StaticResource ShadowEffect}" />
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontFamily" Value="Calibri"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DarkGray"/>
<Setter Property="Effect" Value="{StaticResource DisableShadowEffect}" />
</Trigger>
</Style.Triggers>
</Style>
When used like so it works great:
<CheckBox Width="80" Height="80" Margin="10" Content="{Binding Y2LockAxisString}" Command="{Binding Y2LockDisableEnableCommand}" Style="{StaticResource CBCheckBoxButton}"/>
But I need to add a style so that different commands etc. are called depending on the state of the check box. So I used the basedon property:
<CheckBox Width="80" Height="80" Margin="10">
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource CBCheckBoxButton}">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Command" Value="{Binding ExecuteX2LockDisable}" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Command" Value="{Binding ExecuteX2LockEnable}" />
</Trigger>
</Style.Triggers>
</Style>
</CheckBox>
But the checkbox looks like a default checkbox with none of the appearance elements applied to it.
Why isn't the appearance style working?
It seems you are adding the Style as Content, instead of Style.
Have you tried
<CheckBox Width="80" Height="80" Margin="10">
<CheckBox.Style>
<Style --- snip --->
</Style>
</CheckBox.Style>
</CheckBox>

How To Style Button's Hover And Click Foreground?

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>

Categories