Styles and Templates

General Concepts

  • The way styling works in CSHTML5 is the same as in other recent XAML-based platforms such as UWP, Silverlight, WinRT, and Windows Phone.
  • Please note that WPF uses Triggers by default (for historical reasons), which are not yet supported. You can easily convert a WPF-like style into a style that uses only the VisualStateManager states. Read below for examples.
  • You can use ResourceDictionaries if you wish to organize styles into their own files. You can easily reference a ResourceDictionary by using the "MergedDictionaries" property, as show in the following example (in "App.xaml"):
    <Application
        x:Class="MyApplication1.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="MyResourceDictionary1.xaml"/>
                    <ResourceDictionary Source="Themes/Generic.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Application.Resources>
    </Application>
    
  •  The following features are not yet supported:
    • Implicit Styles - instead, you must specify the styles explicitly, such as in: <Button Style={StaticResource MyButtonStyle} /> - Please note that this will override the default Style and the default ControlTemplate.
    • "DefaultStyleKey"
    • "Generic.xaml" is not automatically referenced. If you wish to use it, you can reference it by using the "MergedDictionaries" property shown above.

 

Styling the Button

To easily customize the appearance of the Button control, you can set Button properties such as: Background, Foreground, Padding, BorderBrush, BorderThickness, Cursor, HorizontalContentAlignment, and VerticalContentAlignment.

If you wish to further customize the Button control, you can apply a custom ControlTemplate.

Below you will find a sample Style and ControlTemplate for the Button control. To use it, you can place the code in the XAML resources (either App.xaml or anywhere in the Button parents' resources), and reference it with: <Button Style={StaticResource ButtonStyle1} />

<Style x:Key="ButtonStyle1" TargetType="Button">
    <Setter Property="Background" Value="#FFE2E2E2"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Padding" Value="12,4,12,4"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border x:Name="OuterBorder"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup Name="CommonStates">
                            <VisualState Name="Normal">
                            </VisualState>
                            <VisualState Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#11000000"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#22000000"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState Name="Disabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#33FFFFFF"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="InnerBorder"
                                Background="{TemplateBinding Background}">
                        <ContentPresenter x:Name="ContentPresenter"
                                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                                Content="{TemplateBinding Content}"
                                                Margin="{TemplateBinding Padding}"
                                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

 

Styling the ToggleButton

To easily customize the appearance of the ToggleButton control, you can set ToggleButton properties such as: Background, Foreground, Padding, BorderBrush, BorderThickness, Cursor, HorizontalContentAlignment, and VerticalContentAlignment.

If you wish to further customize the ToggleButton control, you can apply a custom ControlTemplate.

Below you will find a sample Style and ControlTemplate for the ToggleButton control. To use it, you can place the code in the XAML resources (either App.xaml or anywhere in the ToggleButton parents' resources), and reference it with: <ToggleButton Style={StaticResource ToggleButtonStyle1} />

<Style x:Key="ToggleButtonStyle1" TargetType="ToggleButton">
    <Setter Property="Background" Value="#FFE2E2E2"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Padding" Value="12,4,12,4"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToggleButton">
                <Border x:Name="OuterBorder"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup Name="CommonStates">
                            <VisualState Name="Normal">
                            </VisualState>
                            <VisualState Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#11000000"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#44000000"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState Name="Disabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState Name="Checked">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#33000000"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState Name="CheckedPointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#22000000"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState Name="CheckedPressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#44000000"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState Name="CheckedDisabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#33000000"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState Name="Indeterminate">
                            </VisualState>
                            <VisualState Name="IndeterminatePointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#11000000"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState Name="IndeterminatePressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#22000000"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState Name="IndeterminateDisabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="InnerBorder">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="InnerBorder"
                                Background="{TemplateBinding Background}">
                        <ContentPresenter x:Name="ContentPresenter"
                                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                                Content="{TemplateBinding Content}"
                                                Margin="{TemplateBinding Padding}"
                                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

 

Styling the Expander

To easily customize the appearance of the Expander control, you can set Expander properties such as: Background, Foreground, Padding, BorderBrush, and BorderThickness.

If you wish to further customize the Expander control, you can apply a custom ControlTemplate.

Below you will find a sample Style and ControlTemplate for the Expander control. To use it, you can place the code in the XAML resources (either App.xaml or anywhere in the Expander parents' resources), and reference it with: <Expander Style={StaticResource ExpanderStyle1} Header="MyHeader" Content="MyContent" />

<Style x:Key="ExpanderStyle1" TargetType="Expander">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Expander">
                <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                CornerRadius="3">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="Disabled"/>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused"/>
                            <VisualState x:Name="Unfocused"/>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="ExpansionStates">
                            <VisualState x:Name="Collapsed"/>
                            <VisualState x:Name="Expanded">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="ExpandSite" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <StackPanel>
                        <ToggleButton x:Name="ExpanderButton"
                                                Padding="{TemplateBinding Padding}"
                                                Margin="1"
                                                Content="{TemplateBinding Header}"
                                                ContentTemplate="{TemplateBinding HeaderTemplate}"
                                                Cursor="Hand">
                            <ToggleButton.Template>
                                <ControlTemplate TargetType="ToggleButton">
                                    <Border Padding="{TemplateBinding Padding}">
                                        <VisualStateManager.VisualStateGroups>
                                            <VisualStateGroup x:Name="CommonStates">
                                                <VisualState x:Name="Normal"/>
                                                <VisualState x:Name="Checked">
                                                    <Storyboard>
                                                        <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="arrow" Storyboard.TargetProperty="Data">
                                                            <DiscreteObjectKeyFrame KeyTime="0" Value="M 1,1.5 L 4.5,5 L 8,1.5"/>
                                                        </ObjectAnimationUsingKeyFrames>
                                                    </Storyboard>
                                                </VisualState>
                                            </VisualStateGroup>
                                            <VisualStateGroup x:Name="FocusStates">
                                                <VisualState x:Name="Focused"/>
                                                <VisualState x:Name="Unfocused"/>
                                            </VisualStateGroup>
                                        </VisualStateManager.VisualStateGroups>
                                        <StackPanel Orientation="Horizontal" Margin="5,0,0,0" >
                                            <Path x:Name="arrow" Visibility="Visible" Stroke="#FF555555" Width="9" Height="9" Margin="0,0,3,0" StrokeThickness="3" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="Fill" Data="M 2,1 L 5.5,4.5 L 2,8"/>
                                            <ContentPresenter x:Name="header" Margin="4,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Center" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
                                        </StackPanel>
                                    </Border>
                                </ControlTemplate>
                            </ToggleButton.Template>
                        </ToggleButton>
                        <ContentControl x:Name="ExpandSite"
                                                Visibility="Collapsed" 
                                                Margin="{TemplateBinding Padding}"
                                                Content="{TemplateBinding Content}"
                                                ContentTemplate="{TemplateBinding ContentTemplate}" />
                    </StackPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

 

Styling the TabControl and TabItem

To easily customize the appearance of the TabControl, you can:

  • set TabControl properties such as: Background, Foreground, Padding, BorderBrush, BorderThickness, HorizontalContentAlignment, VerticalContentAlignment
  • set TabItem properties such as: Background, Foreground, SelectedBackground, SelectedForeground, SelectedAccent, Padding, BorderBrush, BorderThickness, Cursor, Margin, HorizontalContentAlignment, VerticalContentAlignment

If you wish to further customize the TabControl, you can apply a custom ControlTemplate to both the TabControl and the TabItem.

Below you will find a sample Style and ControlTemplate for the TabControl and the TabItem controls. To use it, you can place the code in the XAML resources (either App.xaml or anywhere in the Expander parents' resources), and reference it with: <TabControl Style={StaticResource TabControlStyle1}> and <TabItem Style={StaticResource TabItemStyle1}/>

<Style x:Key="TabControlStyle1" TargetType="TabControl">
    <Setter Property="Background" Value="White"/>
    <Setter Property="BorderBrush" Value="#FFDDDDDD"/>
    <Setter Property="BorderThickness" Value="1,1,1,1"/>
    <Setter Property="Padding" Value="5"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TabControl">
                <Border>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="Disabled">
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>

                    <Grid x:Name="TemplateTop" Visibility="Collapsed">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>

                        <TabPanel x:Name="TabPanelTop" />

                        <Border 
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Background="{TemplateBinding Background}" 
                            Grid.Row="1"  
                            CornerRadius="0,0,3,3">
                            <ContentPresenter
                                    x:Name="ContentTop"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="TabItemStyle1" TargetType="TabItem">
    <Setter Property="Background" Value="White"/>
    <Setter Property="BorderBrush" Value="#FFDDDDDD"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="Margin" Value="0,0,5,0"/>
    <Setter Property="Padding" Value="6,0,6,3"/>
    <Setter Property="SelectedBackground" Value="White"/>
    <Setter Property="SelectedForeground" Value="Black"/>
    <Setter Property="SelectedAccent" Value="Blue"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TabItem">
                <StackPanel x:Name="Root">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="PointerOverBorder" Storyboard.TargetProperty="Background">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="#FFCFCFCF"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected"/>
                            <VisualState x:Name="Selected" />
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border
                            x:Name="TemplateTopSelected" Visibility="Collapsed"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="1,0,1,0" 
                            Background="{TemplateBinding SelectedBackground}"
                            CornerRadius="3,3,0,0"
                            Cursor="Arrow">
                        <StackPanel>
                            <Border Height="3" CornerRadius="3,3,0,0" Background="{TemplateBinding SelectedAccent}"/>
                            <ContentControl x:Name="HeaderTopSelected"
                                        Foreground="{TemplateBinding SelectedForeground}" 
                                        Margin="{TemplateBinding Padding}"
                                        />
                        </StackPanel>
                    </Border>
                    <Border x:Name="TemplateTopUnselected" Visibility="Collapsed"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="1,1,1,0" 
                                Background="{TemplateBinding Background}"
                                CornerRadius="3,3,0,0"
                                Cursor="{TemplateBinding Cursor}">
                        <StackPanel>
                            <Border x:Name="PointerOverBorder" Height="2" CornerRadius="3,3,0,0" Background="Transparent"/>
                            <ContentControl x:Name="HeaderTopUnselected"
                                        Foreground="{TemplateBinding Foreground}"
                                        Margin="{TemplateBinding Padding}"/>
                        </StackPanel>
                    </Border>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

 

Styling the CheckBox

By default, the CheckBox uses the native HTML appearance.

If you wish to customize its appearance, you can apply a Style with a ControlTemplate.

To do so, you can copy the XAML code for the ToggleButton above, and just change TargetType="ToggleButton" into TargetType="CheckBox" (2 occurrences!). This will work because CheckBox inherits from ToggleButton.