Trigger is not working. IsMouseOver is not changing style of the Button. I am not sure what is wrong with my code. I am trying to change the style property of the button on mouse over property. It keeps throwing error.
Basically I am trying to use different style on mouse over event
<Style x:Key="FancyButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="{Binding FontSize}"/>
<Setter Property="Foreground" Value="{Binding Foreground}"/>
<Setter Property="FontWeight" Value="{Binding FontWeight}"/>
<Setter Property="Width" Value="{Binding Width}"/>
<Setter Property="Height" Value="{Binding Height}"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0.0" Color="White" />
<GradientStop Offset="0.2" Color="DarkGray" />
<GradientStop Offset="0.6" Color="Black" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Style" Value="{StaticResource ResourceKey=FancyButtonInvertStyle}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="FancyButtonInvertStyle" TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="{Binding FontSize}"/>
<Setter Property="Foreground" Value="{Binding Foreground}"/>
<Setter Property="FontWeight" Value="{Binding FontWeight}"/>
<Setter Property="Width" Value="{Binding Width}"/>
<Setter Property="Height" Value="{Binding Height}"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0.0" Color="Black" />
<GradientStop Offset="0.4" Color="DarkGray" />
<GradientStop Offset="0.6" Color="White" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
Instead of trying to change the Style in the Trigger, change the Background directly in it. Keeps you also from repeating the Style completely over again.
<Style x:Key="FancyButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="{Binding FontSize}"/>
<Setter Property="Foreground" Value="{Binding Foreground}"/>
<Setter Property="FontWeight" Value="{Binding FontWeight}"/>
<Setter Property="Width" Value="{Binding Width}"/>
<Setter Property="Height" Value="{Binding Height}"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0.0" Color="White" />
<GradientStop Offset="0.2" Color="DarkGray" />
<GradientStop Offset="0.6" Color="Black" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0.0" Color="Black" />
<GradientStop Offset="0.4" Color="DarkGray" />
<GradientStop Offset="0.6" Color="White" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
I'm not sure if you even can change the Style of itself in the Trigger the way you intend to, because it is not set via a Setter Tag in the target control itself.
I have a TabControl Template and style, but i am having some issues with the clickable are in the tabs.
You will notice that my tab (Border below) has a width and height specified, but unfortunately, the entire border is not clickable, it is only the text inside it, so if i have one letter in the tab, you have to point your mouse exactly on the letter to select the tab.
How can i make it that if you click anywhere on inside the border it selects the tab?
Here is my ControlTemplate:
<Style x:Key="MainTabItem" TargetType="TabItem">
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border Name="Border" BorderThickness="1,1,1,0" BorderBrush="#EAF1F7" CornerRadius="3,3,0,0" Height="60" Width="70" Margin="-2,0,2,0">
<ContentPresenter x:Name="ContentSite" VerticalAlignment="Center" HorizontalAlignment="Center" ContentSource="Header"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Black" />
<Setter TargetName="Border" Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#EDF1FA" Offset="0"/>
<GradientStop Color="#EAF1F7" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="BorderThickness" Value="0" />
<Setter TargetName="Border" Property="BorderThickness" Value="0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MainTabControl" TargetType="TabControl">
<Setter Property="BorderThickness" Value="2"></Setter>
<Setter Property="BorderBrush" Value="#CFE2F0"></Setter>
<Setter Property="Background" Value="#EAF1F7"/>
<Setter Property="BorderBrush" Value="#EAF1F7"/>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect Direction="150" BlurRadius="20" ShadowDepth="5" Opacity=".3"/>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#EAF1F7" />
<GradientStop Offset=".2" Color="#EAF1F7" />
<GradientStop Offset=".6" Color="#C7D7E4" />
<GradientStop Offset="1" Color="#EAF1F7" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
To the border add Background="Transparent".
The reason is that default value for background is null, and pixels with 'null' value are not hit test visible. Transparent pixels are hit test visible (and that's the main reason why 'null' and 'Transparent' exist together).
I want to change the foreground from a trigger when I press the button, here is the XAML I have so far:
<Window.Resources>
<SolidColorBrush x:Key="FocuseBorder" Color="DarkBlue" ></SolidColorBrush>
<SolidColorBrush x:Key="OverBorder" Color="Blue" />
<SolidColorBrush x:Key="PressdBorder" Color="Red" />
<SolidColorBrush x:Key="DefulateBorder" Color="Black" ></SolidColorBrush>
<LinearGradientBrush x:Key="GradDefulat" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#FF949494" Offset="0"/>
<GradientStop Color="Black" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="GradOver" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FF949494" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="GradPressd" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#FF666868" Offset="0"/>
<GradientStop Color="Black" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="GradFocuse" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="#FF5F5F5F" Offset="1"/>
</LinearGradientBrush>
<Style x:Key="SelectionButton3"
TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Name="grd" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ClipToBounds="False">
<Border x:Name="TheBorder" CornerRadius="10"
Background="{StaticResource GradDefulat}" Height="{Binding Path=Height}" Width="{Binding Path=Width}"
BorderBrush="DarkSlateBlue"> </Border>
<Rectangle Name="rect" Fill="{StaticResource GradDefulat}" Stroke="DarkSlateBlue"
Height="200" Width="50">
<Rectangle.RenderTransform >
<RotateTransform Angle="45" CenterX=" 30" CenterY="25" >
</RotateTransform>
</Rectangle.RenderTransform>
</Rectangle>
<ContentPresenter x:Name="ContentArea" VerticalAlignment="Center" HorizontalAlignment="Center "
Content="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}" />
</Grid>
<ControlTemplate.Triggers >
<Trigger Property="IsDefaulted" Value="True">
<Setter TargetName="TheBorder" Property ="Background" Value="{StaticResource GradDefulat}"/>
<Setter TargetName="TheBorder" Property="BorderBrush" Value="{StaticResource DefulateBorder}"/>
<Setter TargetName="rect" Property ="Fill" Value="{StaticResource GradDefulat}"/>
<Setter TargetName="rect" Property="Stroke" Value="{StaticResource DefulateBorder}"/>
</Trigger>
<!-- Defaulated-->
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="TheBorder" Property="Background" Value="{StaticResource GradOver}"/>
<Setter TargetName="TheBorder" Property="BorderBrush" Value="{StaticResource OverBorder}"/>
<Setter TargetName="rect" Property="Fill" Value="{StaticResource GradOver}"/>
<Setter TargetName="rect" Property="Stroke" Value="{StaticResource OverBorder}"/>
</Trigger>
<!-- Over-->
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="TheBorder" Property="Background" Value="{StaticResource GradFocuse}"/>
<Setter TargetName="TheBorder" Property="BorderBrush" Value="{StaticResource FocuseBorder}"/>
<Setter TargetName="rect" Property="Fill" Value="{StaticResource GradFocuse}"/>
<Setter TargetName="rect" Property="Stroke" Value="{StaticResource FocuseBorder}"/>
</Trigger>
<!--Focuse-->
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="TheBorder" Property="Background" Value="{StaticResource GradPressd}"/>
<Setter TargetName="TheBorder" Property="BorderBrush" Value="{StaticResource PressdBorder}"/>
<Setter TargetName="rect" Property="Fill" Value="{StaticResource GradPressd}"/>
<Setter TargetName="rect" Property="Stroke" Value="{StaticResource PressdBorder}"/>
</Trigger>
<!-- Focuse-->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
English isn't my first language, so I apologize for the lack of detail.
How can i display custom sort direction image in wpf datagrid header?
I use this style in my datagrid. How can I add images for ascending and descending sort directions?
<Style x:Key="DataGridColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}" >
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#fbfdfc" Offset="0.1" />
<GradientStop Color="#d4d5d9" Offset="0.9" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Padding" Value="3"/>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="SortDirection" Value="{x:Null}" />
</MultiTrigger.Conditions>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#ffd8a8" Offset="0.0" />
<GradientStop Color="#ffad41" Offset="0.5" />
<GradientStop Color="#fedf78" Offset="0.9" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Black" />
</MultiTrigger>
</Style.Triggers>
</Style>
If you want to change the triangles you need to override the Template, you can trigger on the SortDirection and display a different image accordingly. (Get the default templates from MSDN (Default WPF Themes link))
I want to style the indeterminate state of a WPF checkbox. We have a treeview control with checkboxes, and we want the indeterminate state to represent that some descendants are checked and some are unchecked.
The solution I'm seeing everywhere is to override the default control template for a checkbox and do what I need to do.
I have two problems with that:
I can't find the control template
for a normal Aero checkbox. This
one:
http://msdn.microsoft.com/en-us/library/ms752319.aspx
looks goofy.
The control template I get from Expression Blend has that BulletChrome element in it, and I can't figure out what to do with that.
So does anyone know where to get a checkbox control template that looks "normal" or is there an easier way to just style the indeterminate state by itself?
I'm sure there's an easy way I'm just overlooking... Right?
Try this (modified from the article that publicgk linked to)
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="CheckRadioFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="14,0,0,0"
StrokeThickness="1"
Stroke="Black"
StrokeDashArray="1 2"
SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="EmptyCheckBoxFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="1"
StrokeThickness="1"
Stroke="Black"
StrokeDashArray="1 2"
SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="CheckBoxFillNormal"
Color="#F4F4F4"/>
<SolidColorBrush x:Key="CheckBoxStroke"
Color="#8E8F8F"/>
<Style x:Key="{x:Type CheckBox}"
TargetType="{x:Type CheckBox}">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background"
Value="{StaticResource CheckBoxFillNormal}"/>
<Setter Property="BorderBrush"
Value="{StaticResource CheckBoxStroke}"/>
<Setter Property="BorderThickness"
Value="1"/>
<Setter Property="FocusVisualStyle"
Value="{StaticResource EmptyCheckBoxFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator Background="Transparent"
SnapsToDevicePixels="true">
<BulletDecorator.Bullet>
<theme:BulletChrome Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderPressed="{TemplateBinding IsPressed}"
IsChecked="{TemplateBinding IsChecked}"/>
</BulletDecorator.Bullet>
<ContentPresenter Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="{x:Null}">
<!-- TODO: Do Stuff Here -->
</Trigger>
<Trigger Property="HasContent"
Value="true">
<Setter Property="FocusVisualStyle"
Value="{StaticResource CheckRadioFocusVisual}"/>
<Setter Property="Padding"
Value="4,0,0,0"/>
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<CheckBox IsChecked="True" Content="Checked"/>
<CheckBox IsChecked="{x:Null}" Content="Unknown"/>
<CheckBox IsChecked="False" Content="Not Checked"/>
</StackPanel>
</Window>
Have you already tried to download the Aero Theme xaml and looked into it?
Where can I download Microsoft's standard WPF themes from?
You can use CheckBox styling from the classic theme located at:
C:\Program Files (x86)\Microsoft Expression\Blend 4\SystemThemes\Wpf\classic.xaml
This implementation has a Path representing the checkbox mark called CheckMarkPath. I simply replaced this Path with a filled Rectangle to get these results:
Call me crazy, but I've actually reimplemented standard Aero checkbox in pure XAML. If you want to customize Aero checkbox, it's a good starting point. You can find other styles in my repository on GitHub (specific commit, in case files are moved).
BulletCommon.xaml (common resources for CheckBox and RadioButton)
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xx="clr-namespace:Alba.WpfThemeGenerator.Markup">
<!-- Colors -->
<!-- Background overlay -->
<SolidColorBrush x:Key="Bullet.BackgroundOverlay.Hover" Color="#DEF9FA"/>
<SolidColorBrush x:Key="Bullet.BackgroundOverlay.Pressed" Color="#C2E4F6"/>
<SolidColorBrush x:Key="Bullet.BackgroundOverlay.Disabled" Color="#F4F4F4"/>
<!-- Border overlay -->
<SolidColorBrush x:Key="Bullet.BorderOverlay.Hover" Color="#3C7FB1"/>
<SolidColorBrush x:Key="Bullet.BorderOverlay.Pressed" Color="#2C628B"/>
<SolidColorBrush x:Key="Bullet.BorderOverlay.Disabled" Color="#ADB2B5"/>
<!-- Inner border -->
<LinearGradientBrush x:Key="Bullet.InnerBorder.Disabled" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#E1E3E5" Offset="0.25"/>
<GradientStop Color="#E8E9EA" Offset="0.5"/>
<GradientStop Color="#F3F3F3" Offset="1"/>
</LinearGradientBrush>
<!-- Indeterminate inner border -->
<LinearGradientBrush x:Key="Bullet.InnerBorder.IndeterminateDisabled" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#BFD0DD" Offset="0"/>
<GradientStop Color="#BDCBD7" Offset="0.5"/>
<GradientStop Color="#BAC4CC" Offset="1"/>
</LinearGradientBrush>
<!-- Inner fill -->
<LinearGradientBrush x:Key="Bullet.InnerFill.Normal" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#CBCFD5" Offset="0.2"/>
<GradientStop Color="#F7F7F7" Offset="0.8"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="Bullet.InnerFill.Hover" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#B1DFFD" Offset="0.2"/>
<GradientStop Color="#E9F7FE" Offset="0.8"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="Bullet.InnerFill.Pressed" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#7FBADC" Offset="0.2"/>
<GradientStop Color="#D6EDF9" Offset="0.8"/>
</LinearGradientBrush>
<!-- Indeterminate fill -->
<LinearGradientBrush x:Key="Bullet.Fill.Indeterminate" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#2FA8D5" Offset="0.2"/>
<GradientStop Color="#25598C" Offset="0.8"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="Bullet.Fill.IndeterminateHover" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#33D7ED" Offset="0.2"/>
<GradientStop Color="#2094CE" Offset="0.8"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="Bullet.Fill.IndeterminatePressed" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#17447A" Offset="0.2"/>
<GradientStop Color="#218BC3" Offset="0.8"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="Bullet.Fill.IndeterminateDisabled" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#C0E5F3" Offset="0.2"/>
<GradientStop Color="#BDCDDC" Offset="0.8"/>
</LinearGradientBrush>
<!-- Styles -->
<Style x:Key="Bullet.FocusVisual.Normal">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="14,0,0,0" SnapsToDevicePixels="True"
StrokeThickness="1" Stroke="{xx:SystemBrush ControlText}" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Bullet.FocusVisual.Empty">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="1" SnapsToDevicePixels="True"
StrokeThickness="1" Stroke="{xx:SystemBrush ControlText}" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
CheckBox.xaml (resources for CheckBox)
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xx="clr-namespace:Alba.WpfThemeGenerator.Markup">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="BulletCommon.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!-- Colors -->
<SolidColorBrush x:Key="CheckBox.Stroke" Color="#8E8F8F"/>
<SolidColorBrush x:Key="CheckBox.Fill" Color="#F4F4F4"/>
<!-- Check mark -->
<SolidColorBrush x:Key="CheckBox.Glyph.Stroke.Normal" Color="#FFFFFF"/>
<SolidColorBrush x:Key="CheckBox.Glyph.Stroke.Pressed" Color="#B2FFFFFF"/>
<SolidColorBrush x:Key="CheckBox.Glyph.Fill.Normal" Color="#31347C"/>
<SolidColorBrush x:Key="CheckBox.Glyph.Fill.Pressed" Color="#B231347C"/>
<SolidColorBrush x:Key="CheckBox.Glyph.Fill.Disabled" Color="#AEB7CF"/>
<!-- Inner border -->
<LinearGradientBrush x:Key="CheckBox.InnerBorder" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#AEB3B9" Offset="0.25"/>
<GradientStop Color="#C2C4C6" Offset="0.5"/>
<GradientStop Color="#EAEBEB" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="CheckBox.InnerBorder.Hover" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#79C6F9" Offset="0.3"/>
<GradientStop Color="#79C6F9" Offset="0.5"/>
<GradientStop Color="#D2EDFD" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="CheckBox.InnerBorder.Pressed" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#54A6D5" Offset="0.3"/>
<GradientStop Color="#5EB5E4" Offset="0.5"/>
<GradientStop Color="#C4E5F6" Offset="1"/>
</LinearGradientBrush>
<!-- Indeterminate inner border -->
<LinearGradientBrush x:Key="CheckBox.InnerBorder.Indeterminate" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#2A628D" Offset="0"/>
<GradientStop Color="#245479" Offset="0.5"/>
<GradientStop Color="#193B55" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="CheckBox.InnerBorder.IndeterminateHover" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#29628D" Offset="0"/>
<GradientStop Color="#245479" Offset="0.5"/>
<GradientStop Color="#193B55" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="CheckBox.InnerBorder.IndeterminatePressed" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#193B55" Offset="0"/>
<GradientStop Color="#245479" Offset="0.5"/>
<GradientStop Color="#29628D" Offset="1"/>
</LinearGradientBrush>
<!-- Indeterminate highlight -->
<LinearGradientBrush x:Key="CheckBox.Highlight.Indeterminate" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#80FFFFFF" Offset="0"/>
<GradientStop Color="#00FFFFFF" Offset="0.5"/>
<GradientStop Color="#003333A0" Offset="0.5"/>
<GradientStop Color="#003333A0" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="CheckBox.Highlight.IndeterminateHover" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#80FFFFFF" Offset="0"/>
<GradientStop Color="#00FFFFFF" Offset="0.5"/>
<GradientStop Color="#003333A0" Offset="0.5"/>
<GradientStop Color="#803333A0" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="CheckBox.Highlight.IndeterminatePressed" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#00FFFFFF" Offset="0.5"/>
<GradientStop Color="#20FFFFFF" Offset="1"/>
</LinearGradientBrush>
<!-- Images -->
<PathGeometry x:Key="CheckBox.Glyph.Geometry">
<PathFigure StartPoint="9.0, 1.833" IsClosed="True">
<LineSegment Point="10.667, 3.167"/>
<LineSegment Point="7, 10.667"/>
<LineSegment Point="5.333, 10.667"/>
<LineSegment Point="3.333, 8.167"/>
<LineSegment Point="3.333, 6.833"/>
<LineSegment Point="4.833, 6.5"/>
<LineSegment Point="6, 8"/>
</PathFigure>
</PathGeometry>
<!-- Styles -->
<Style x:Key="{x:Type CheckBox}" TargetType="{x:Type CheckBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource Bullet.FocusVisual.Empty}"/>
<Setter Property="Foreground" Value="{xx:SystemBrush ControlText}"/>
<Setter Property="Background" Value="{StaticResource CheckBox.Fill}"/>
<Setter Property="BorderBrush" Value="{StaticResource CheckBox.Stroke}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator Background="Transparent" SnapsToDevicePixels="True">
<BulletDecorator.Bullet>
<Grid Width="13" Height="13">
<Rectangle x:Name="Background" Margin="0" Fill="{TemplateBinding Background}"/>
<Rectangle x:Name="BackgroundOverlay" Margin="0"/>
<Rectangle x:Name="InnerFill" Margin="3" Fill="{StaticResource Bullet.InnerFill.Normal}"/>
<Rectangle x:Name="InnerBorder" Margin="2" Stroke="{StaticResource CheckBox.InnerBorder}"/>
<Rectangle x:Name="Highlight" Margin="3"/>
<Path x:Name="GlyphStroke" Margin="0" StrokeThickness="1.5" Data="{StaticResource CheckBox.Glyph.Geometry}"/>
<Path x:Name="GlyphFill" Margin="0" Data="{StaticResource CheckBox.Glyph.Geometry}"/>
<Rectangle x:Name="Border" Margin="0" Stroke="{TemplateBinding BorderBrush}"/>
<Rectangle x:Name="BorderOverlay" Margin="0"/>
</Grid>
</BulletDecorator.Bullet>
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
RecognizesAccessKey="True"/>
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="True">
<!-- if (HasContent) -->
<Setter Property="FocusVisualStyle" Value="{StaticResource Bullet.FocusVisual.Normal}"/>
<Setter Property="Padding" Value="4,0,0,0"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<!-- if (IsMouseOver) -->
<Setter TargetName="BackgroundOverlay" Property="Fill" Value="{StaticResource Bullet.BackgroundOverlay.Hover}"/>
<Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.InnerFill.Hover}"/>
<Setter TargetName="BorderOverlay" Property="Stroke" Value="{StaticResource Bullet.BorderOverlay.Hover}"/>
<Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource CheckBox.InnerBorder.Hover}"/>
</Trigger>
<Trigger Property="IsChecked" Value="{x:Null}">
<!-- if (IsChecked == null) -->
<Setter TargetName="Highlight" Property="Stroke" Value="{StaticResource CheckBox.Highlight.Indeterminate}"/>
<Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.Fill.Indeterminate}"/>
<Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource CheckBox.InnerBorder.Indeterminate}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<!-- if (IsPressed) -->
<Setter TargetName="BackgroundOverlay" Property="Fill" Value="{StaticResource Bullet.BackgroundOverlay.Pressed}"/>
<Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.InnerFill.Pressed}"/>
<Setter TargetName="BorderOverlay" Property="Stroke" Value="{StaticResource Bullet.BorderOverlay.Pressed}"/>
<Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource CheckBox.InnerBorder.Pressed}"/>
</Trigger>
<MultiTrigger>
<!-- if (IsChecked == null && IsMouseOver) -->
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="{x:Null}"/>
<Condition Property="IsMouseOver" Value="True"/>
</MultiTrigger.Conditions>
<Setter TargetName="Highlight" Property="Stroke" Value="{StaticResource CheckBox.Highlight.IndeterminateHover}"/>
<Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.Fill.IndeterminateHover}"/>
<Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource CheckBox.InnerBorder.IndeterminateHover}"/>
</MultiTrigger>
<MultiTrigger>
<!-- if (IsChecked == null && IsPressed) -->
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="{x:Null}"/>
<Condition Property="IsPressed" Value="True"/>
</MultiTrigger.Conditions>
<Setter TargetName="Highlight" Property="Stroke" Value="{StaticResource CheckBox.Highlight.IndeterminatePressed}"/>
<Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.Fill.IndeterminatePressed}"/>
<Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource CheckBox.InnerBorder.IndeterminatePressed}"/>
</MultiTrigger>
<MultiTrigger>
<!-- if (IsChecked == true && IsPressed) -->
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="IsPressed" Value="True"/>
</MultiTrigger.Conditions>
<Setter TargetName="GlyphStroke" Property="Stroke" Value="{StaticResource CheckBox.Glyph.Stroke.Pressed}"/>
<Setter TargetName="GlyphFill" Property="Fill" Value="{StaticResource CheckBox.Glyph.Fill.Pressed}"/>
</MultiTrigger>
<MultiTrigger>
<!-- if (IsChecked == true && !IsPressed) -->
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="IsPressed" Value="False"/>
</MultiTrigger.Conditions>
<Setter TargetName="GlyphStroke" Property="Stroke" Value="{StaticResource CheckBox.Glyph.Stroke.Normal}"/>
<Setter TargetName="GlyphFill" Property="Fill" Value="{StaticResource CheckBox.Glyph.Fill.Normal}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<!-- if (!IsEnabled) -->
<Setter Property="Foreground" Value="{xx:SystemBrush GrayText}"/>
<Setter TargetName="InnerFill" Property="Fill" Value="{x:Null}"/>
<Setter TargetName="GlyphStroke" Property="Stroke" Value="{x:Null}"/>
<Setter TargetName="BorderOverlay" Property="Stroke" Value="{StaticResource Bullet.BorderOverlay.Disabled}"/>
<Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource Bullet.InnerBorder.Disabled}"/>
</Trigger>
<MultiTrigger>
<!-- if (IsChecked == null && !IsEnabled) -->
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="{x:Null}"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.Fill.IndeterminateDisabled}"/>
<Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource Bullet.InnerBorder.IndeterminateDisabled}"/>
</MultiTrigger>
<MultiTrigger>
<!-- if (IsChecked == true && !IsEnabled) -->
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter TargetName="GlyphFill" Property="Fill" Value="{StaticResource CheckBox.Glyph.Fill.Disabled}"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Notes:
{xx:SystemBrush ControlText} is a shortcut for {DynamicResource {x:Static SystemColors.ControlTextBrushKey}}. You can either use that shortcut or just find and replace with regex.
RTL, animations, weird cases are not supported.
This style is slower than using BulletChrome which is heavily optimized.
The below code is a sample check box with three state.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<!-- Focus Style -->
<SolidColorBrush x:Key="InputBackgroundFocused" Color="Orange"></SolidColorBrush>
<Style x:Key="CheckBoxFocusVisualStyle">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border CornerRadius="2" Margin="0,0,4,3" BorderThickness="2" BorderBrush="{StaticResource InputBackgroundFocused}" Background="Transparent"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Fill Brushes -->
<LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#FFF" Offset="0.0"/>
<GradientStop Color="#CCC" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="HorizontalNormalBrush" StartPoint="0,0" EndPoint="1,0">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#FFF" Offset="0.0"/>
<GradientStop Color="#CCC" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="LightBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#FFF" Offset="0.0"/>
<GradientStop Color="#EEE" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="HorizontalLightBrush" StartPoint="0,0" EndPoint="1,0">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#FFF" Offset="0.0"/>
<GradientStop Color="#EEE" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="DarkBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#FFF" Offset="0.0"/>
<GradientStop Color="#AAA" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="PressedBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#BBB" Offset="0.0"/>
<GradientStop Color="#EEE" Offset="0.1"/>
<GradientStop Color="#EEE" Offset="0.9"/>
<GradientStop Color="#FFF" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
<SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />
<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
<SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />
<!-- Border Brushes -->
<LinearGradientBrush x:Key="NormalBorderBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#CCC" Offset="0.0"/>
<GradientStop Color="#444" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="HorizontalNormalBorderBrush" StartPoint="0,0" EndPoint="1,0">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#CCC" Offset="0.0"/>
<GradientStop Color="#444" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="DefaultedBorderBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#777" Offset="0.0"/>
<GradientStop Color="#000" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="PressedBorderBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#444" Offset="0.0"/>
<GradientStop Color="#888" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA" />
<SolidColorBrush x:Key="SolidBorderBrush" Color="#888" />
<SolidColorBrush x:Key="LightBorderBrush" Color="#AAA" />
<!-- Miscellaneous Brushes -->
<SolidColorBrush x:Key="GlyphBrush" Color="#444" />
<SolidColorBrush x:Key="LightColorBrush" Color="#DDD" />
<Style TargetType="{x:Type CheckBox}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="FocusVisualStyle" Value="{DynamicResource CheckBoxFocusVisualStyle}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Border x:Name="Border"
Width="17"
Height="17"
CornerRadius="2"
Background="{StaticResource NormalBrush}"
BorderThickness="1"
BorderBrush="{StaticResource NormalBorderBrush}">
<Path
Width="11" Height="11"
x:Name="CheckMark"
SnapsToDevicePixels="False"
Stroke="{StaticResource GlyphBrush}"
StrokeThickness="2"
Data="M 2,4 C 2,4 3,5 5,13 C 5,13 5,3 12,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>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" />
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<CheckBox>Hello</CheckBox>
<CheckBox IsThreeState="True">asdfsdaf</CheckBox>
</StackPanel>
</Grid>
The best software to modify the existing look and feel of the controls is Expression Blend. If you want to change the existing look and feel and you have to modify the Control Template of the control.
Another option may be to style a toggle button as it has multiple states as well. In past projects I have created custom toggle buttons with multiple states that look and function as chekcboxes. I did use blend to make the changes but in using a tggle button as the base I was able to create a more customized look and feel for the various states of the button/chekcbox. Using a toggle button can bypass a lot of the chrome related issues that are tightly boud to a standard chekcbox control.
Have you thought about using SimpleStyles as the base for control?
By selecting this control from the Assets panel, Expression Blend will place a new resource dictonary in your project that you can use to modify the style as you please. Might be a better starting point than trying to hack into the Chrome for the standard checkbox.
Using the template from Blend:
To make BulletChrome work, you need to add a reference to PresentationFramework.Aero, and add the xml namespace declaration for the "theme" namespace:
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
I didn't try this myself but I believe it should work (I've done it with Luna).
You can set the checkbox's IsThreeState property to true.
This, however, allows toggling the checkbox's value to null.
If that is undesired, you can instead add to your CheckBox's Template a trigger for the null value, just like Greg Bacchus shows in his answer:
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="{x:Null}">
<!-- TODO: Do Stuff Here -->
</Trigger>
</ControlTemplate.Triggers>