Table of Contents

Modify Control Themes

A control theme in Avalonia UI consists of styles, control themes and resources that determine templates and appearance settings of the controls.

This topic demonstrates approaches to modifying specific theme settings and styles for individual and all Eremex Avalonia UI controls in your project.

Default Theme

The Eremex.Avalonia.Themes.DeltaDesign theme is the default theme for the Eremex Controls. You need to include this theme in your project and register it in the App.axaml file. Otherwise, Eremex controls will be displayed blank.

To modify specific settings (for instance, colors or templates of control elements) of the currently used theme we suggest that you see the source code of the theme. You can find and download the theme source code on GitHub at: Eremex Controls Themes.

Modification of theme settings includes two steps:

  • Locate a target style, resource or template that you need to override.
  • Modify the target style/resource/template for all or individual controls.

You need to know the key of a resource to override this resource in your application.

Locate a Target Style, Resource or Template

Exploring the source code of the theme allows you to locate the theme settings that you need to modify.

The image below demonstrates the structure of the DeltaDesign theme source code:

deltadesigntheme-structure

  • Controls folder — Contains theme settings for the Eremex and standard Avalonia UI controls.
  • Charts folder — Contains theme settings for the Eremex Chart controls.
  • Variants — Contains theme settings for the controls for the Light and Dark theme variants.

Theme settings (templates, colors, margins, etc.) are defined as dynamic or static resources.

Declaration of Dynamic Resources in the Eremex Paint Theme

Theme settings that depend on a theme variant (Light or Dark) are defined as dynamic resources (DynamicResource). These theme settings include most of the colors for the Eremex controls.

The following code snippet shows the style selector that initializes the ColumnHeaderControl.Foreground property in a TreeList control. This property determines the foreground color of TreeList column headers. The value of the ColumnHeaderControl.Foreground property is defined as a dynamic resource with the key Text/Neutral/Secondary.

<!-- Eremex.Avalonia.Themes.DeltaDesign\Controls\TreeListControl.axaml -->
<Styles ...>
    <Style Selector="mxdcv|ColumnHeaderControl">
        <Setter Property="Foreground" Value="{DynamicResource	Text/Neutral/Secondary}" />
        <!-- ... -->
    </Style>
</Styles>

The Text/Neutral/Secondary resource has different values for the Light and Dark theme variants:

<!-- Eremex.Avalonia.Themes.DeltaDesign\Variants\Light\Colors.axaml file -->
<SolidColorBrush x:Key="Text/Neutral/Secondary" Color="#ff424d4d"/>

<!-- Eremex.Avalonia.Themes.DeltaDesign\Variants\Dark\Colors.axaml file -->
<SolidColorBrush x:Key="Text/Neutral/Secondary" Color="#ffc6d2d2"/>

Note that the Text/Neutral/Secondary resource also determines values of other theme settings for other controls. You can search the theme source code for the "Text/Neutral/Secondary" string to find all references to this resource.

Resources related to the Light and Dark theme variants are merged by the Eremex paint theme into two resource dictionaries:

  • The resource dictionary with the key "Default" combines resources related to the Light theme variant. See the Eremex.Avalonia.Themes.DeltaDesign\Variants\Light\Variant.axaml file.
  • The resource dictionary with the key "Dark" combines resources related to the Dark theme variant. See the Eremex.Avalonia.Themes.DeltaDesign\Variants\Dark\Variant.axaml file.

You need to know the keys of these dictionaries to override dynamic resources for the Light and Dark theme variants in your projects.

Declaration of Static Resources in an Eremex Paint Theme

Many theme settings are the same for the Light and Dark theme variants. These settings are defined as static resources (StaticResource). They include:

  • Settings that specify the inner layout of control elements (for example, size and margins of the elements)
  • Templates used to render inner elements and context menus

For example, the Eremex.Avalonia.Themes.DeltaDesign\Controls\TreeListControl.axaml file contains theme settings for a TreeList control. The font size of TreeList column headers is defined as a static resource with the key "ColumnHeaderFontSize".

<!-- Eremex.Avalonia.Themes.DeltaDesign\Controls\TreeListControl.axaml file -->
<Styles ...>
    <Style Selector="mxdcv|ColumnHeaderControl">
        <Setter Property="FontSize" Value="{StaticResource ColumnHeaderFontSize}" />
        <!-- ... -->
    </Style>

    <Styles.Resources>
        <x:Double x:Key="ColumnHeaderFontSize">12</x:Double>
    </Styles.Resources>
</Styles>

Theme Style Selectors for Style Classes

The DeltaDesign theme contains control themes and style selectors for the Eremex and standard Avalonia controls that have specific style classes defined. When you set a specific style class for a control (using the control's Classes property), the theme applies a corresponding style selector(s).

For instance, you can apply the warning style class to a CheckBox, as follows:

<CheckBox Content="Important" Classes="warning"/>

In this case, the DeltaDesign theme applies a style selector that targets this style class:

<!-- Eremex.Avalonia.Themes.DeltaDesign\Controls\StandardControls\CheckBox.axaml -->

<ControlTheme x:Key="{x:Type CheckBox}" TargetType="CheckBox">
    <!-- Warning State -->
    <Style Selector="^.warning /template/ Border#NormalRectangle">
        <Setter Property="BorderBrush" Value="{DynamicResource CheckBoxWarningRectBorderBrush}" />
    </Style>
    <!-- ... -->
</ControlTheme>

The checkbox that has this style class is shown below:

themes-checkbox-styleclass-warning

The following list shows main style classes for which the DeltaDesign theme contains style selectors:

  • accent — Accented appearance settings. Target standard Avalonia controls: Button, RepeatButton.

    theme-button-styleclass-accent

  • warning — Appearance settings to indicate warings and errors. Target standard Avalonia controls: Button, RepeatButton, CheckBox, RadioButton.

    theme-button-styleclass-warning

    You can combine the accent and warning style classes:

    theme-button-styleclass-accent-warning

  • secondary — Appearance settings for controls displayed on a gray background. Target Eremex controls: editors with a built-in text box (TextEditor, ButtonEditor, ComboBoxEditor, SpinEditor, DateEditor, and so on), and SegmentedEditor. Target standard Avalonia controls: TextBox, Button, RepeatButton, ToggleButton, CheckBox, ProgressBar, RadioButton, and Slider.

    theme-button-styleclass-secondary

Modify a dynamic resource shared by multiple controls

Multiple controls can use the same resource. To modify a shared resource for all target controls within your application, change this resource at the application level using the Application.Resources property. Use the Window.Resources property to modify a shared resource for target controls within a window.

Example — Modify the focused row's border brush for controls in your application for the Light and Dark theme variants

Assume that you need to modify the brush used to paint the border of the focused row in DataGrid, TreeList and/or ListView controls in your entire application. This brush should have different values for the Light and Dark theme variants.

The default paint theme determines the focused row's border brush as a dynamic resource with the key Outline/Accent/Focus.

<!-- Eremex.Avalonia.Themes.DeltaDesign\Controls\DataGridControl.axaml file -->
<Style Selector="mxdgv|DataGridRowControl:focusedState /template/ Border#FocusBorder, mxdgv|DataGridRowControl:focusedAndSelectedState /template/ Border#FocusBorder">
    <!-- ... -->
    <Setter Property="BorderBrush" Value="{DynamicResource Outline/Accent/Focus}" />
</Style>

<!-- Eremex.Avalonia.Themes.DeltaDesign\Controls\ListViewControl.axaml -->
<Style Selector="mxl|ListViewGroupControl:focus-visible/template/Rectangle#PART_Border">
    <Setter Property="Stroke" Value="{DynamicResource Outline/Accent/Focus}"/>
</Style>

<!-- Eremex.Avalonia.Themes.DeltaDesign\Controls\TreeListControl.axaml -->
<Style Selector="mxtlv|TreeListRowControl:focusedState /template/ Border#FocusBorder, mxtlv|TreeListRowControl:focusedAndSelectedState /template/ Border#FocusBorder">
	<Setter Property="BorderThickness" Value="1" />
	<Setter Property="BorderBrush" Value="{DynamicResource Outline/Accent/Focus}" />
</Style>

In the default theme, the Outline/Accent/Focus resource has different values for the Light and Dark theme variants:

<!-- Eremex.Avalonia.Themes.DeltaDesign\Variants\Light\Colors.axaml file -->
<ResourceDictionary xmlns="https://github.com/avaloniaui" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!-- ... -->
    <SolidColorBrush x:Key="Outline/Accent/Focus" Color="#ff129190"/>
</ResourceDictionary>

<!-- Eremex.Avalonia.Themes.DeltaDesign\Variants\Dark\Colors.axaml file -->
<ResourceDictionary xmlns="https://github.com/avaloniaui" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!-- ... -->
    <SolidColorBrush x:Key="Outline/Accent/Focus" Color="#ff36afb0"/>
</ResourceDictionary>

Follow the steps below to modify the focused row's border brush for all controls in the application for the Light abd Dark theme variants.

  1. In your project, create the "ModifiedResources.axaml" file in the "Resources" folder.

  2. Define two resource dictionaries in this file with the "Default" and "Dark" keys for the Light and Dark theme variants, respectively.

<ResourceDictionary xmlns="https://github.com/avaloniaui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.ThemeDictionaries>

        <!-- Override resources for the Light theme variant -->
        <ResourceDictionary x:Key="Default">
            
        </ResourceDictionary>

        <!-- Override resources for the Dark theme variant -->
        <ResourceDictionary x:Key="Dark">
            
        </ResourceDictionary>
        
    </ResourceDictionary.ThemeDictionaries>   
</ResourceDictionary>
  1. Define values of the Outline/Accent/Focus resource in the "Default" and "Dark" resource dictionaries:
<ResourceDictionary xmlns="https://github.com/avaloniaui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.ThemeDictionaries>

        <!-- Override resources for the Light theme variant -->
        <ResourceDictionary x:Key="Default">
            <SolidColorBrush x:Key="Outline/Accent/Focus" Color="Blue"/>
        </ResourceDictionary>

        <!-- Override resources for the Dark theme variant -->
        <ResourceDictionary x:Key="Dark">
            <SolidColorBrush x:Key="Outline/Accent/Focus" Color="Orange"/>
        </ResourceDictionary>
        
    </ResourceDictionary.ThemeDictionaries>   
</ResourceDictionary>
  1. In the App.axaml file, merge the resources from the "Resources/ModifiedResources.axaml" file into the application's resources.
<Application ...>
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceInclude Source="/Resources/ModifiedResources.axaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>
  1. Run the application to see the result. When the light theme variant is enabled, the focused row border is painted in blue. When the dark theme variant is applied, the orange color is used.

themes-example-modify-focusedrowborder-dark

Modify theme resources for a specific control

You can use the control's Resources property to change specific resources for this control only. Other controls are not affected by this resource modification.

Example - Modify an individual Button's color in the pressed and focused states

The DeltaDesign theme contains control themes and style selectors that modify colors of specific standard Avalonia UI controls so that their appearance matches the appearance of the Eremex controls placed on the same window.

The default appearance of the standard Button control in the pressed state painted by the DeltaDesign theme is shown below:

theme-button-default-appearance

In the pressed state, the following style selectors are applied:

<!-- Eremex.Avalonia.Themes.DeltaDesign\Controls\StandardControls\Button.axaml -->
<ControlTheme x:Key="{x:Type Button}" TargetType="Button">
    <!-- Pressed State -->
    <Style Selector="^:pressed">
        <Style Selector="^ /template/ Border#PART_BackgroundBorder">
            <Setter Property="Background" Value="{DynamicResource ButtonBackgroundPressed}" />
        </Style>
        <Style Selector="^  /template/ ContentPresenter#PART_ContentPresenter">
            <Setter Property="Foreground" Value="{DynamicResource ButtonForegroundPressed}" />
            <Setter Property="Opacity" Value="0.8"/>
        </Style>
    </Style>
    <!--Focus Border-->
    <Style Selector="^:focus /template/ Border#PART_ButtonBorder">
        <Setter Property="BorderBrush" Value="{DynamicResource ButtonFocusBorderBrush}" />
        <Setter Property="BorderThickness" Value="{StaticResource EditorBorderThickness}"/>
    </Style>
    <!-- ... -->
</ControlTheme>

To change colors of an individual Button in the pressed and focused state, modify the ButtonBackgroundPressed, ButtonForegroundPressed and ButtonFocusBorderBrush resources from the Button.Resources property.

theme-button-modified-appearance

<Button Content="Simple Button" HorizontalAlignment="Center" >
    <Button.Resources>
        <SolidColorBrush x:Key="ButtonBackgroundPressed" Color="LightSeaGreen" />
        <SolidColorBrush x:Key="ButtonForegroundPressed" Color="Snow" />
        <SolidColorBrush x:Key="ButtonFocusBorderBrush" Color="SlateGray" />
    </Button.Resources>
</Button>

Modify theme resources for controls within a Window

If you use the Window.Resources property to change theme resources, these changes are propagated to corresponding controls within this window.

Example - Modify accented buttons within a Window for the Light and Dark theme variants

The DeltaDesign theme contains specific style selectors applied when you set the accent and/or warning style classes for the standard Avalonia Button control. This example shows how to override the appearances settings of accented buttons in a Window for the Light and Dark theme variants.

You can apply the accent and warning style classes to give emphasis to the button:

<Button Content="Warning&amp;Accent Button" Classes="warning accent"/>

theme-button-default-appearance-accent-warning

See the Eremex.Avalonia.Themes.DeltaDesign\Controls\StandardControls\Button.axaml file to find out style selectors applied to accented buttons in the normal, hovered, pressed and disabled states. The code snippet below demonstrates two style selectors for an accented button's normal state:

<!-- Eremex.Avalonia.Themes.DeltaDesign\Controls\StandardControls\Button.axaml file -->
<ControlTheme x:Key="{x:Type Button}" TargetType="Button">
    <!-- WarningAccent style -->
    <Style Selector="^.warning.accent">
        <Style Selector="^ /template/ Border#PART_BackgroundBorder">
            <Setter Property="Background" Value="{DynamicResource ButtonWarningAccentBackground}" />
        </Style>
        <Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
            <Setter Property="Foreground" Value="{DynamicResource ButtonWarningAccentForeground}" />
        </Style>
        <!-- ... -->
    </Style>
    <!-- ... -->
</ControlTheme>

Use the Window.Resources property to override background colors for accented buttons for the Light and Dark theme variants at the Window level. The code below overrides the corresponding theme resources in the resource dictionaries with the Default and Dark keys. These dictionaries define resources for the Light and Dark theme variants, respectively:

<mx:MxWindow 
    xmlns:mx="https://schemas.eremexcontrols.net/avalonia">

    <mx:MxWindow.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <!--Resources for the Light theme variant-->
                <ResourceDictionary x:Key="Default">
                    <SolidColorBrush x:Key="ButtonWarningAccentBackground" Color="Purple" />
                </ResourceDictionary>

                <!--Resources for the Dark theme variant-->
                <ResourceDictionary x:Key="Dark">
                    <SolidColorBrush x:Key="ButtonWarningAccentBackground" Color="LightYellow" />
                </ResourceDictionary>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </mx:MxWindow.Resources>
    <!-- ... -->
</mx:MxWindow>

theme-button-modified-appearance-accent-warning

You may also want to change brushes related to additional states of accented buttons:

  • Hovered — ButtonWarningAccentBackgroundPointerOver and ButtonWarningAccentForegroundPointerOver
  • Pressed — ButtonWarningAccentBackgroundPressed and ButtonWarningAccentForegroundPressed
  • Disabled — ButtonWarningAccentBackgroundDisabled and ButtonWarningAccentForegroundDisabled.

Modify controls' styles defined in the Eremex Paint Theme

If you explore the DeltaDesign paint theme source code, you can see style selectors that change not only the controls' brushes and colors, but also other appearance settings. For instance, style selectors specify the size of the controls' inner elements, and templates, which define the layout and content of the controls.

You can override these style selectors in your application using the following properties:

  • Application.Styles — A collection of styles to be applied to controls on the application level.
  • Window.Styles — A collection of styles to be applied to controls within a window.
  • Control.Styles — A collection of styles to be applied to a specific control.

Example - Modify a style for a color toggle button in a ColorEditor control at the application level

This example shows how to change the appearance and template of color toggle buttons in the ColorEditor and PopupColorEditor controls. New styles are applied to all ColorEditor and PopupColorEditor controls within the application.

theme-coloreditor-colorcheckbutton

You can find the default styles for color toggle buttons in the DeltaDesign theme source code. Create your own styles based on this style definition.

<!-- Eremex.Avalonia.Themes.DeltaDesign\Controls\Editors\ColorEditor.axaml -->
<!--Color Toggle Button-->
<ControlTheme x:Key="{x:Type mxev:ColorToggleButton}" TargetType="mxev:ColorToggleButton">
    <Setter Property="CornerRadius" Value="{StaticResource EditorCornerRadius}"/>
    <Setter Property="BorderThickness" Value="{StaticResource EditorBorderThickness}"/>
    <Setter Property="Width" Value="{StaticResource ColorButtonDefaultSize}"/>
    <!-- ... -->
    <Setter Property="Template">
        <ControlTemplate>
            <Border x:Name="PART_ExternalBorder"
                    CornerRadius="{TemplateBinding CornerRadius}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    ...>
                <Border x:Name="PART_InternalBorder"
                        CornerRadius="{TemplateBinding CornerRadius}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        ...>
                    <Path x:Name="PART_CheckGlyph"
                            Stretch="None"
                            Fill="{Binding $parent[mxev:ColorToggleButton].BorderBrush}"
                            Data="{StaticResource CheckBoxCheckIcon}"
                            .../>
                </Border>
            </Border>
        </ControlTemplate>
    </Setter>
</ControlTheme>

Follow the steps below to change the appearance of color toggle buttons at the application level:

  1. Create the "ModifiedStyles.axaml" file in the "Resources" folder of your project.

  2. Add the following code to the "ModifiedStyles.axaml" file. This code overrides the styles for the ColorToggleButton class

<Styles xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mxev="clr-namespace:Eremex.AvaloniaUI.Controls.Editors.Visuals;assembly=Eremex.Avalonia.Controls">
    <Styles.Resources>
        <RectangleGeometry x:Key="ColorCheckedIcon" Rect="0,0,7,7" />
    </Styles.Resources>
    
    <Style Selector="mxev|ColorToggleButton">
        <Setter Property="CornerRadius" Value="3"/>
        <Setter Property="Template">
            <ControlTemplate>
                <Border x:Name="PART_ExternalBorder"
                                CornerRadius="{TemplateBinding CornerRadius}"
                                BorderThickness="2"
                                BorderBrush="LightSteelBlue"
                                Background="{TemplateBinding Background}">
                    <Border x:Name="PART_InternalBorder"
                                    CornerRadius="{TemplateBinding CornerRadius}"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    BorderBrush="{TemplateBinding BorderBrush}"
                                    Background="{TemplateBinding Background}">
                        <Path x:Name="PART_CheckGlyph"
                                    Stretch="None"
                                    VerticalAlignment="Center"
                                    HorizontalAlignment="Center"
                                    Data="{StaticResource ColorCheckedIcon}"
                                    Margin="0"
                                    Width = "7"
                                    Height="7"
                        />
                    </Border>
                </Border>
            </ControlTemplate>
        </Setter>
    </Style>
</Styles>
  1. In the App.axaml file, include styles from the "Resources/ModifiedStyles.axaml" file into the Application.Styles collection.
<Application ...>
    <Application.Styles>
        <theme:DeltaDesignTheme/>
        <StyleInclude Source="/Resources/ModifiedStyles.axaml"/>
    </Application.Styles>
</Application>
  1. Run the application to see the result.

theme-coloreditor-colorcheckbutton-result