Windows App Development

Styling and Templates in WinUI

WinUI provides a powerful and flexible system for styling your applications and customizing the appearance of controls through templates. This enables you to create visually rich and unique user experiences that align with your brand or design guidelines.

Key Concepts: Understanding Resources, Styles, and Control Templates is fundamental to effective UI customization in WinUI.

Resources

Resources are objects that can be referenced from multiple places within your XAML. This includes things like colors, brushes, dimensions, strings, and even entire control templates. In WinUI, resources are typically defined in the <Page.Resources> or <Application.Resources> sections.

Defining and Using Resources

You can define resources using keys, which allow you to retrieve them programmatically or within XAML using the StaticResource markup extension.


<Page.Resources>
    <x:String x:Key="AppTitle">My Awesome App</x:String>
    <SolidColorBrush x:Key="PrimaryAccentBrush" Color="#0078D4"/>
</Page.Resources>

<TextBlock Text="{StaticResource AppTitle}" Style="{StaticResource PageTitleStyle}"/>
<Button Background="{StaticResource PrimaryAccentBrush}" Content="Click Me"/>
            

Styles

Styles are a collection of property settings that can be applied to elements to define their appearance and behavior. They are particularly useful for creating consistent styling across multiple controls of the same type or for defining specific visual states.

Creating and Applying Styles

Styles are defined within resource dictionaries and can be applied directly to a control or inherited by other styles.


<Page.Resources>
    <Style TargetType="Button" x:Key="PrimaryButtonStyle">
        <Setter Property="Background" Value="{ThemeResource SystemAccentColor}"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="Padding" Value="12,6"/>
        <Setter Property="CornerRadius" Value="4"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            CornerRadius="{TemplateBinding CornerRadius}"
                            Padding="{TemplateBinding Padding}">
                        <ContentPresenter HorizontalAlignment="Center"
                                        VerticalAlignment="Center"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>

<Button Content="Save" Style="{StaticResource PrimaryButtonStyle}"/>
            

Implicit Styles

If you omit the x:Key from a Style definition, it becomes an "implicit style" and will be automatically applied to all elements of the specified TargetType within its scope, unless overridden by an explicit style.


<Application.Resources>
    <Style TargetType="TextBlock">
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="Foreground" Value="{StaticResource TextColorBrush}"/>
    </Style>
</Application.Resources>
            

Control Templates

Control templates define the visual structure and behavior of a control. They allow you to completely replace the default rendering of a control with your own custom visual tree. This is where you can achieve the most dramatic UI transformations.

Understanding Control Templates

A ControlTemplate typically consists of a root element (often a Grid or Border) and contains child elements that represent the visual parts of the control, such as buttons, text, or images. The ContentPresenter is a key element used to display the content of the control.

When creating custom templates, it's often best to start by copying the default template for the control you want to modify and then making your changes.

Example: Customizing a Button Template


<Page.Resources>
    <ControlTemplate x:Key="CustomButtonTemplate" TargetType="Button">
        <Grid Background="{TemplateBinding Background}"
              CornerRadius="8"
              Padding="15,8">
            <ContentPresenter HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            TextBlock.Foreground="{TemplateBinding Foreground}" />
        </Grid>
        <!-- Add VisualStateManager for hover, pressed, disabled states here -->
    </ControlTemplate>

    <Style TargetType="Button" x:Key="FancyButton">
        <Setter Property="Background" Value="LightGray"/>
        <Setter Property="Foreground" Value="DarkSlateGray"/>
        <Setter Property="Template" Value="{StaticResource CustomButtonTemplate}"/>
    </Style>
</Page.Resources>

<Button Content="Submit" Style="{StaticResource FancyButton}" />
            

Theme Resources

WinUI uses theme resources to manage colors, fonts, and other UI elements that adapt to the system's light or dark mode. You can access these using the ThemeResource markup extension.

Common Theme Resources


<TextBlock Text="Welcome!"
           Foreground="{ThemeResource TextColorPrimary}"
           FontSize="24"/>
            

Visual States

Visual states allow you to define different visual appearances for a control based on its state (e.g., Normal, PointerOver, Pressed, Disabled). These are managed within a VisualStateManager inside a control template.

Mastering control templates and visual states is key to creating dynamic and responsive WinUI applications.

Example: Basic Visual States in a Template


<ControlTemplate TargetType="Button">
    <Border x:Name="BorderElement"
            Background="{TemplateBinding Background}"
            CornerRadius="5">
        <ContentPresenter HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        TextBlock.Foreground="{TemplateBinding Foreground}"/>
    </Border>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Normal"/>
            <VisualState x:Name="PointerOver">
                <Storyboard>
                    <ColorAnimation To="#FFC1E0"
                                    Storyboard.TargetName="BorderElement"
                                    Storyboard.TargetProperty="Background.Color"/>
                </Storyboard>
            </VisualState>
            <VisualState x:Name="Pressed">
                <Storyboard>
                    <ColorAnimation To="#FF99CC"
                                    Storyboard.TargetName="BorderElement"
                                    Storyboard.TargetProperty="Background.Color"/>
                </Storyboard>
            </VisualState>
            <VisualState x:Name="Disabled">
                <Storyboard>
                    <ColorAnimation To="LightGray"
                                    Storyboard.TargetName="BorderElement"
                                    Storyboard.TargetProperty="Background.Color"/>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</ControlTemplate>