Skip to main content
All docs
V24.1

Modify Theme Resources

  • 7 minutes to read

You can customize a visual element’s theme resources (brushes, thicknesses, colors, styles, templates, and so on) as described below.

If you use the DevExpress WPF Controls NuGet packages, you should additionally install DevExpress WPF Controls on your machine. The installation includes the DevExpress WPF Themes source code.

Use the WPF Theme Designer

The WPF Theme Designer is a standalone tool that allows you to create custom themes based on built-in DevExpress WPF Application Themes.

To change a theme resource with the WPF Theme Designer, perform the following steps:

  1. Download the WPF Theme Designer separately from DevExpress WPF Controls.
  2. Create a custom theme.
  3. Use the Inspect Element tool to locate control elements whose appearance you want to change.
  4. Modify theme resources of the elements.
  5. Export an assembly with your custom theme.
  6. Reference this assembly in your application.

Topic: WPF Theme Designer - Create and Apply a New Custom Theme.

Advantages

  • You can export a modified theme as an assembly.
  • You can use the Inspect Element tool to locate an element’s properties and source XAML code.
  • The Custom Theme Upgrade tool allows you to update your custom theme to a newer version of DevExpress WPF Controls and resolves possible update conflicts.
  • The Preview Window allows you to apply your custom theme to DevExpress WPF Controls and see a preview of your changes.

Disadvantage

Use XAML Resources in Your Application’s Code

You can copy theme resources[1] from the DevExpress WPF Controls source code to your application, modify these theme resources, and use them as a XAML resources in your project.

Advantages

Disadvantages

  • You need to find a control element in your application’s visual tree and identify the theme resource[1] you should change.
  • You may encounter update issues when you upgrade to a newer version of DevExpress WPF Controls.

Find an Element’s Theme Resources

To access an element’s theme resource[1], locate this element in your application’s visual tree. You can use Visual Studio’s Live Visual Tree, Snoop (used in this topic), the WPF Theme Designer Inspect Element tool, or another tool that analyzes the visual tree.

This article shows how to search for a template that defines the GridColumn filter icon’s appearance:

GridControl - Filter Icon

1. Find an Element in the Visual Tree

  1. Attach the Snoop tool to your application with a Data Grid control.
  2. Hold Ctrl + Shift and hover the mouse pointer over a grid column’s filter icon. This icon consists of a Grid with four Path items.

GridControl - Snoop

2. Identify the Item You Want to Change

Use the item’s unique attributes to identify the item you want to change: control type, name, or property. This sample uses the Path’s Data property.

GridControl Templates - Snoop

3. Find the Element in Theme Source Code

Locate the element in the source code of the DevExpress WPF Theme whose appearance you want to change. You can use the Visual Studio’s built-in search tool (used in this topic), the WPF Theme Designer’s Individual Colors window, or another tool that can search for text in files.

Follow the steps below to locate the GridColumn filter icon’s template in the Office2016White theme’s source code.

  1. Open the Office2016White theme’s project. The default folder path is C:\Program Files\DevExpress 24.1\Components\Sources\XPF\DevExpress.Xpf.Themes\Office2016White\Office2016White.csproj.
  2. Search for an element whose Path’s Data property value is F1 M 1296.5.

GridControl - VisualStudio Search

Recommendations on How to Modify Theme Resources

When you modify theme resources, your modifications may affect DevExpress WPF Controls and lead to exceptions, incorrect operation, and other issues. To avoid these issues, we recommend that you follow the instructions below.

  • Do not remove elements whose names start with PART_ and do not change the names/types of these elements. DevExpress WPF Controls may use them in code-behind.

    To hide these elements, set the element’s Visibility property to Collapsed. This approach has no effect in the scenario described in the next point.

  • DevExpress WPF Controls may change the Visibility of PART_ editors in code-behind. Do not modify the Visibility property in those theme resources[1]. To hide these elements, set their Opacity property value to 0.

  • Do not remove elements from complex brushes. Animated DevExpress WPF Controls use these elements.

    The following code snippet contains an example of a complex LinearGradientBrush with GradientStop elements:

    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#FFD1E4FC" Offset="0" />
        <GradientStop Color="#FFAED1F6" Offset="1" />
        <GradientStop Color="#FFB5D0F1" Offset="0.5" />
        <GradientStop Color="#FFA4C5ED" Offset="0.5" />
    </LinearGradientBrush>
    
  • DevExpress WPF Controls may contain the cs:Name attribute. You should remove it from your custom theme resource or specify the following XML namespaces to ignore it:

    <Window ...
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:cs="colorscheme_ignorable_uri"
        mc:Ignorable="cs">
        <Window.Resources>
            <ControlTemplate x:Key="{dxgt:GridColumnHeaderThemeKey ResourceKey=ControlTemplate}" 
                             TargetType="{x:Type dxg:GridColumnHeaderBase}">
                <Grid>
                <!-- ... -->
                    <Border ...
                        cs:Name="Border_0001"/>
                </Grid>
            </ControlTemplate>
        </Window.Resources>
    </Window>
    

Apply Modified Theme Resources To Your Application

Paste modified theme resources[1] to resources of the target element (control, window, or an application) and choose one of the following options:

  • To apply modified resources to all DevExpress WPF Themes, set the resource’s IsThemeIndependent property to true.

    The following code sample modifies resources for all GridColumnHeaderBase elements within the window in all DevExpress WPF Themes:

    <Window ... 
        xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys">
        <Window.Resources>
            <ControlTemplate x:Key="{dxgt:GridColumnHeaderThemeKey ResourceKey = ColumnFilterTemplate, IsThemeIndependent = true}">
                <!-- ... -->
            </ControlTemplate>
        </Window.Resources>
    </Window>
    
  • To modify resources for a specific theme, specify the resource’s ThemeName property.

    You can find a list of available ThemeName property values in the Theme List topic (see the Theme Name column).

    The following code sample modifies resources only in the Office2019Colorful theme:

    <Window ... 
        xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys">
        <Window.Resources>
            <ControlTemplate x:Key="{dxgt:GridColumnHeaderThemeKey ResourceKey=ColumnFilterTemplate,ThemeName=Office2019Colorful}" TargetType="{x:Type ToggleButton}">
                <!-- ... -->
            </ControlTemplate>
        </Window.Resources>
    </Window>
    

If you do not specify a resource’s IsThemeIndependent or ThemeName properties, the resource is applied in the DeepBlue theme only.

Requirements for Modified Theme Resources

The modified theme resource[1] should meet the following requirements:

  1. Make sure that the theme resource is visible for its target element.

    Topic: Overview of XAML resources (WPF .NET)

  2. Reference assemblies and copy namespaces that the theme resource uses.
  3. Place theme resources used in popups and MessageBoxes in the App.xaml resources.
  4. If a theme resource uses static resources (Brushes, Converters, and others), you should also copy them to your application.

Use Different Theme Resources with Different Themes

  1. Create theme resources[1] for each theme that you use.
  2. Specify the ThemeName property for each created theme resource.

    You can find a list of available ThemeName property values in the Theme List topic (see the Theme Name column).

The following code sample uses different templates for Office2013 and MetropolisDark application themes:

<Window ... 
    xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys">
    <Window.Resources>
        <ControlTemplate x:Key="{dxgt:GridColumnHeaderThemeKey ResourceKey=ColumnFilterTemplate,ThemeName=Office2013}" TargetType="{x:Type ToggleButton}">
             <!-- ... -->
        </ControlTemplate>
        <ControlTemplate x:Key="{dxgt:GridColumnHeaderThemeKey ResourceKey=ColumnFilterTemplate,ThemeName=MetropolisDark}" TargetType="{x:Type ToggleButton}">
             <!-- ... -->
        </ControlTemplate>
    </Window.Resources>
</Window>

Use a Theme’s Dynamic Resources

An original theme resource may use the theme’s dynamic resources:

<Window ... 
    xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys">
    <Window.Resources>
        <ControlTemplate ...>
            <Grid>
                <Border BorderBrush="{DynamicResource {dxgt:TableViewThemeKey ResourceKey=ColumnChooserBorderBrush}}">
            </Grid>
        </ControlTemplate>
    <Window.Resources>
</Window>

If you specify your modified resource’s IsThemeIndependent property, it still uses resources from the default theme (DeepBlue). To use resources from the applied theme, perform the following steps:

  1. Reference the dxi="http://schemas.devexpress.com/winfx/2008/xaml/core/internal" XAML namespace.
  2. Change the modified theme resource’s DynamicResource to a dxi:ThemeResource. The ThemeResource markup extension dynamically sets its target property to a resource from the target element’s applied theme. The target element must be in your application’s visual tree.

    <TargetElement TargetProperty="{dxi:ThemeResource {ThemeKey}}" />
    

The following code sample sets the Border’s (TargetElement) BorderBrush (TargetProperty) property value to a resource (ThemeKey) from the target element’s applied theme:

<Window ... 
    xmlns:dxi="http://schemas.devexpress.com/winfx/2008/xaml/core/internal"
    xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys">
    <Window.Resources>
        <ControlTemplate ...>
            <Grid>
                <Border BorderBrush="{dxi:ThemeResource {dxgt:TableViewThemeKey ResourceKey=ColumnChooserBorderBrush}}">
            </Grid>
        </ControlTemplate>
    <Window.Resources>
</Window>

View Example: Load Resources from DevExpress Themes Dynamically with the ThemeResource extension

Note

The ThemeResource markup extension is explicitly not supported for the standard WPF DataGrid.

Footnotes
  1. Brushes, thicknesses, colors, styles, templates, and others.