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:
- Download the WPF Theme Designer separately from DevExpress WPF Controls.
- Create a custom theme.
- Use the Inspect Element tool to locate control elements whose appearance you want to change.
- Modify theme resources of the elements.
- Export an assembly with your custom theme.
- 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
- You should download the WPF Theme Designer separately from DevExpress WPF Controls.
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
- You can modify a theme resource in fewer steps than with the WPF Theme Designer.
You can use a modified theme resource with all DevExpress WPF Themes.
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:
1. Find an Element in the Visual Tree
- Attach the Snoop tool to your application with a Data Grid control.
- 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.
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.
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.
- 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
. - Search for an element whose Path’s
Data
property value is F1 M 1296.5.
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 toCollapsed
. This approach has no effect in the scenario described in the next point.DevExpress WPF Controls may change the
Visibility
ofPART_
editors in code-behind. Do not modify theVisibility
property in those theme resources[1]. To hide these elements, set theirOpacity
property value to0
.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 totrue
.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:
Make sure that the theme resource is visible for its target element.
- Reference assemblies and copy namespaces that the theme resource uses.
- Place theme resources used in popups and MessageBoxes in the
App.xaml
resources. - 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
- Create theme resources[1] for each theme that you use.
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:
- Reference the
dxi="http://schemas.devexpress.com/winfx/2008/xaml/core/internal"
XAML namespace. Change the modified theme resource’s
DynamicResource
to adxi:ThemeResource
. TheThemeResource
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>
Note
The ThemeResource
markup extension is explicitly not supported for the standard WPF DataGrid.