Back to Devexpress

Lightweight Themes

wpf-404442-common-concepts-themes-lightweight-themes.md

latest24.7 KB
Original Source

Lightweight Themes

  • Oct 22, 2025
  • 11 minutes to read

DevExpress lightweight themes visually replicate regular themes, but offer quicker startup times and consume less memory.

You can compare regular and lightweight theme performance on your machine. Run our specially-designed application available in the following repository:

View Example: WPF Lightweight Themes - Performance Tests

Use Lightweight Themes

  1. Add the DevExpress.Wpf.ThemesLW NuGet package to your project or reference the DevExpress.Xpf.ThemesLW.v25.2 assembly.
  2. Set the CompatibilitySettings.UseLightweightThemes property to true in the application constructor.
  3. Set the ApplicationThemeHelper.ApplicationThemeName property to a theme name at application startup. The LightweightTheme class contains available lightweight themes.
csharp
using DevExpress.Xpf.Core;
// ...
public partial class App : Application {
    static App() {
        CompatibilitySettings.UseLightweightThemes = true;
        ApplicationThemeHelper.ApplicationThemeName = LightweightTheme.Win11Dark.Name;
    }
}
vb
Imports DevExpress.Xpf.Core
' ...
Public Partial Class App
    Inherits Application

    Private Shared Sub New()
        CompatibilitySettings.UseLightweightThemes = True
        ApplicationThemeHelper.ApplicationThemeName = LightweightTheme.Win11Dark.Name
    End Sub
End Class

Lightweight themes change the appearance of all controls within an application. If a standard control should keep its original appearance, set the attached dx:LightweightThemeManager.AllowStandardControlsTheming property to false.

Alternatively, you can use the static LightweightThemeManager.AllowStandardControlsTheming property to keep original appearance for all standard controls within the application:

csharp
public partial class App : Application {
    static App() {
        CompatibilitySettings.UseLightweightThemes = true;
        ApplicationThemeHelper.ApplicationThemeName = LightweightTheme.Win11Dark.Name;
        LightweightThemeManager.AllowStandardControlsTheming = false;
    }
}
vb
Public Partial Class App
    Inherits Application

    Private Shared Sub New()
        CompatibilitySettings.UseLightweightThemes = True
        ApplicationThemeHelper.ApplicationThemeName = LightweightTheme.Win11Dark.Name
        LightweightThemeManager.AllowStandardControlsTheming = False
    End Sub
End Class

Theme List

Windows 11 Themes

Win11Dark

Win11Light

Windows 10 Themes

Win10Dark

Win10Light

Office 2019 Themes

Office2019Black

Office2019Colorful (Default Theme)

Office2019HighContrast

Visual Studio 2019 Themes

VS2019Blue

VS2019Dark

VS2019Light

Set Theme-Specific Values in XAML

LWThemeValue

The LWThemeValue extension allows you to specify a property value (an appearance attribute) that takes effect when the corresponding (specified) theme is active. The extension dynamically updates the value when the theme changes.

The code snippet below applies different changes to multiple appearance attributes for corresponding themes when the application switches between them:

xaml
<Border BorderThickness="{LWThemeValue 0, Win11=1}" />
<Border BorderThickness="{LWThemeValue 0, Win11=1, Win11Light=2}" />
<Border BorderThickness="{LWThemeValue '0,1,2,3', Win11='1,2'}" />
<Border BorderThickness="{LWThemeValue Default='0,1,2,3', Win11='1,2'}" />
<Border BorderThickness="{LWThemeValue 
                            Default={StaticResource DefaultBorderThickness},    
                            Win11={StaticResource Win11BorderThickness}}" />

<TextBlock Text="{LWThemeValue 'Hello', Win11='HELLO'}"/>
<TextBlock Visibility="{LWThemeValue 'Visible', Win11='Collapsed'}"/>

<Image Source="{LWThemeValue 
                   'pack://application:,,,/MyApp;component/Images/Image1.svg', 
                    Win11='pack://application:,,,/MyApp;component/Images/Image2.svg'}"/>

For properties that support Color and Brush types, you can also use colors from the current theme palette:

xaml
<!-- Defines color explicitly -->
<Border Background="{LWThemeValue #FFFFFF, Win11=#000000}" />

<!-- Uses palettes as a source -->
<Border Background="{LWThemeValue 
                        Win11Light=Brush.Delimiter, 
                        Win11Dark=Brush.Border}" />

Note

If you assign LWThemeValue to a dependency property, the extension creates a standard WPF Binding using a value converter.

If you assign LWThemeValue to a regular property, the extension creates a binder that handles theme changes and updates the property through the reflection.

Types Conversion

Use the TargetType property to convert LWThemeValue properties to the specific type.

In the example below, the EditValue parent property requires the value of the Object type. The LWThemeValue.Win11 property returns the String value. Use the TargetType property to convert String to Object.

xaml
<dxe:PopupColorEdit EditValue="{LWThemeValue 
                                    ...
                                    Win11=Color.Custom.Green, /* string */ 
                                    TargetType=Color /* convert string to object */
                                }" />

Types Support

The LWThemeValue supports the following types:

  • Primitive types: int, byte, double, char, string, etc.
  • Common structures: Point, Rect, Size, TimeSpan, DateTime, TimeSpanRange, and DateTimeRange.
  • UI-related types: Uri, ImageSource, and GridLength.
  • Theme-based types: Color and Brush.
  • Any Enum type.

For unsupported complex types, use manual binding as follows:

xaml
<Border BorderThickness="{Binding RelativeSource={RelativeSource Self}, 
                          Path=dx:LightweightThemeManager.CurrentTheme, Converter={...}}"/>

Alternatively, you can create a LWThemeValueExtension descendant:

csharp
public class MyLWThemeValueExtension : LWThemeValueExtension {
    public object Office2019ColorfulEnhancedContrast { get; set; } = NULL;
    protected override object GetActualValue() {
        if(LightweightThemeManager.CurrentTheme == LightweightTheme.Office2019BlackEnhancedContrast) {
            return
                Office2019ColorfulEnhancedContrast != NULL
                ? Office2019ColorfulEnhancedContrast
                : Office2019 != NULL
                ? Office2019
                : Default;
        }
        return base.GetActualValue();
    }
}
vb
Public Class MyLWThemeValueExtension
    Inherits LWThemeValueExtension

    Public Property Office2019ColorfulEnhancedContrast As Object = Nothing

    Protected Overrides Function GetActualValue() As Object
        If LightweightThemeManager.CurrentTheme = LightweightTheme.Office2019BlackEnhancedContrast Then
            If Office2019ColorfulEnhancedContrast IsNot Nothing Then
                Return Office2019ColorfulEnhancedContrast
            ElseIf Office2019 IsNot Nothing Then
                Return Office2019
            Else
                Return Default
            End If
        End If
        Return MyBase.GetActualValue()
    End Function

End Class

LWThemeDictionary

The LWThemeDictionary extension allows you to switch between resources depending on the applied theme.

The code snippet below switches between resources when the current theme changes:

xaml
<!-- Dictionary1.xaml -->
<ResourceDictionary ...>
    <SolidColorBrush x:Key="myBrush">Red</SolidColorBrush>
</ResourceDictionary>

<!-- Dictionary2.xaml -->
<ResourceDictionary ...>
    <SolidColorBrush x:Key="myBrush">Blue</SolidColorBrush>
</ResourceDictionary>

<UserControl ...>
    <UserControl.Resources>
        <LWThemeDictionary 
            Default="pack://application:,,,/Resources/Dictionary1.xaml" 
            Win11="pack://application:,,,/Resources/Dictionary2.xaml">
    </UserControl.Resources>

    <Border Background="{DynamicResource myBrush}"/>
</UserControl>

Note

We recommend that you use the absolute URI with the ‘pack:’ prefix to specify LWThemeDictionary sources. The relative URI may not work at Design Time.

Palettes

Palettes allow you to integrate colors (for example, corporate colors) into your application and customize colors used in themes. You can create a custom palette or use predefined palettes.

View Example: WPF Lightweight Themes - Use Palette Resources in Custom Controls

A Palette is a Dictionary of named colors. Each entry includes a ColorName and a Color value. You can use a ColorName to assign the corresponding Color to any number of UI elements.

Predefined Palettes

The LightweightTheme class contains predefined palette themes alongside classic themes. The following code sample applies the VS2019Dark theme with the DeepSea palette:

csharp
ApplicationThemeHelper.ApplicationThemeName = LightweightTheme.VS2019DarkDeepSea.Name;
vb
ApplicationThemeHelper.ApplicationThemeName = LightweightTheme.VS2019DarkDeepSea.Name

You can use the RibbonGalleryItemThemePaletteSelectorBehavior to allow users to apply palette themes at runtime.

Custom Palettes

You can create a new lightweight theme with custom palette colors:

  1. Create a Dictionary with a palette color name and its new color.

  2. Use the LightweightTheme.OverridePalette method to create a new theme.

  3. Register the created theme in LightweightThemeManager.

  4. Apply this theme to your application.

csharp
protected override void OnStartup(StartupEventArgs e) {
    var customPalette = new Dictionary<string, Color> {
        {"Foreground", (Color)ColorConverter.ConvertFromString("#FFFF7200")},
        {"SelectionBackground", Colors.Orange}
    };
    var customTheme = LightweightTheme.OverridePalette(
        basedOn: LightweightTheme.Win10Dark, 
        name: "CustomTheme", 
        isPaletteTheme: false, 
        displayName: "Custom Theme", 
        colors: customPalette
    );

    LightweightThemeManager.RegisterTheme(customTheme);
    ApplicationThemeHelper.ApplicationThemeName = customTheme.Name;

    base.OnStartup(e);
}
vb
Protected Overrides Sub OnStartup(ByVal e As StartupEventArgs)
    Dim customPalette = New Dictionary(Of String, Color) From {
        {"Foreground", CType(ColorConverter.ConvertFromString("#FFFF7200"), Color)},
        {"SelectionBackground", Colors.Orange}
    }
    Dim customTheme = LightweightTheme.OverridePalette(
        basedOn:=LightweightTheme.Win10Dark, 
        name:="CustomTheme", 
        isPaletteTheme:=False, 
        displayName:="Custom Theme", 
        colors:=customPalette
    )

    LightweightThemeManager.RegisterTheme(customTheme)
    ApplicationThemeHelper.ApplicationThemeName = customTheme.Name

    MyBase.OnStartup(e)
End Sub

The LightweightTheme.OverridePalette method contains the isPaletteTheme parameter. Set this parameter to false to create a new theme displayed in the theme selector:

Alternatively, you can set the isPaletteTheme parameter to true to create a new palette theme displayed in the palette selector:

The following properties specify how to display themes in theme/palette selectors:

PropertyDescription
ShowInThemeSelectorSpecifies whether to display the theme in the theme/palette selector.
DisplayCategorySpecifies the theme category name.
DisplayNameSpecifies the theme name in the theme selector.
PaletteNameSpecifies the palette theme name in the palette selector.
SmallGlyphGets or sets the theme’s small icon.
LargeGlyphGets or sets the theme’s large icon.
SvgGlyphGets or sets the theme’s SVG icon.
SvgPaletteGets or sets the color palette for the SvgGlyph.

Obtain Palette Colors

Obtain Default Palette Colors

In XAML:

The LWThemeValue extension allows you to obtain resources from the applied theme and use them in your application. Use the following syntax to assign theme colors to properties: {LWThemeValue Default=[Brush/Color].[ColorName]}. You can find color names and values for different themes in the Palette Color List.

xaml
<Button Foreground="{LWThemeValue Default=Brush.Button.CheckedBorder}"/>

You can also specify an alternative color that is applied for a specific theme or all themes of a category:

xaml
<Button Foreground="{LWThemeValue 
                     Default=Brush.Control.NeutralBackground, 
                     Win10=#FFFF0000}"
        Background="{LWThemeValue 
                     Default=Brush.Custom.Blue, 
                     Win11Dark=Brush.Editor.PressedBorder, 
                     Win11Light=Brush.Button.CheckedBorder}"/>

In Code:

To obtain default palette colors in code, use the PaletteName dictionary:

csharp
public MainWindow() {
    InitializeComponent();
    LightweightThemeManager.CurrentThemeChanged += (_, __) => UpdateButtonBrush();
}

// ...

private void UpdateButtonBrush()
{
    var palette = LightweightThemeManager.CurrentTheme.Palette;

    if (palette.Contains("Brush.Button.CheckedBorder") &&
        palette["Brush.Button.CheckedBorder"] is Brush brush)
    {
        myButton.Background = brush;
    }
}
vb
Public Sub New()
    InitializeComponent()
    AddHandler LightweightThemeManager.CurrentThemeChanged, Sub(_, __) UpdateButtonBrush()
End Sub

// ...

Private Sub UpdateButtonBrush()
    Dim palette = LightweightThemeManager.CurrentTheme.Palette

    If palette.Contains("Brush.Button.CheckedBorder") Then
        Dim brush = TryCast(palette("Brush.Button.CheckedBorder"), Brush)
        If brush IsNot Nothing Then
            myButton.Background = brush
        End If
    End If
End Sub

Obtain Custom Palette Colors

You can obtain colors defined in your custom palette and assign them to a property. To do this, use one of the following techniques:

  • Find a resource that uses your custom color:

  • Add your custom colors to the LightweightTheme.Palette resource dictionary:

Preload Lightweight Theme Resources

You can use ApplicationThemeHelper.Preload and ApplicationThemeHelper.PreloadAsync methods to preload lightweight theme resources and speed up the display time of subsequent windows. These methods preload theme resources for specified DevExpress controls or for the entire UserControl.

Refer to the following help topic for more information: Preload Theme Resources.

Modify Lightweight Theme Resources

Note

We do not recommend that you modify lightweight theme resources for tasks that can be achieved with the help of the control’s built-in API. Lightweight theme resources and keys can change in the future. As a result, an update to a newer DevExpress version can be more complicated.

You can customize visual element theme resources (brushes, thicknesses, colors, styles, templates, and so on) as described in the following topic: Modify Theme Resources.

Lightweight themes are designed to use a set of specific theme keys. Each DevExpress WPF assembly contains the LWKeyExtension class. You can use it to modify lightweight theme resources defined in this control library:

xaml
<Window ...
        xmlns:dxrt="http://schemas.devexpress.com/winfx/2008/xaml/ribbon/themekeys"
        xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys">
    <Window.Resources>
        <!-- Overrides the 'GridColumnHeader.Background' theme resource in all themes: -->
        <SolidColorBrush x:Key="{dxgt:LWKey GridColumnHeader.Background}" 
                         Color="Red"/>

        <!-- Overrides the 'Backstage.Foreground' theme resource to 'Red' in all themes except 'Office2019Colorful'.
        In this theme, the code sets the resource to 'Blue': -->
        <SolidColorBrush x:Key="{dxrt:LWKey Backstage.Foreground}" 
                         Color="Red"/>
        <SolidColorBrush x:Key="{dxrt:LWKey Backstage.Foreground, ThemeName='Office2019Colorful'}" 
                         Color="Blue"/>

        <!-- LWKeys are similar to regular keys in most cases: -->
        <!-- For example, the '{dxgt:LWKey GridColumnHeader.Background}' key is equal to -->
        <!-- '{dxgt:GridColumnHeaderThemeKey ResourceKey=Background}' -->
    </Window.Resources>
</Window>

In lightweight themes, you can use DynamicResource and StaticResource markup extensions without any restrictions. For example, the following code is valid in any place within your application:

xaml
<StackPanel ...
            xmlns:dxrt="http://schemas.devexpress.com/winfx/2008/xaml/ribbon/themekeys"
            xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys">
    <!-- The DynamicResource is updated each time the application theme is changed. -->
    <!-- The StaticResource is resolved only once at the application startup. -->
    <Button Background="{StaticResource {dxgt:LWKey GridControl.Foreground}}"/>
    <Button Background="{DynamicResource {dxrt:LWKey Backstage.Foreground}}"/>
</StackPanel>

Theme keys used to modify regular theme resources can also work in lightweight themes. The only difference is that regular theme keys in lightweight themes become theme independent (regardless of the ThemeName property value):

xaml
<Window ...
        xmlns:dxrt="http://schemas.devexpress.com/winfx/2008/xaml/ribbon/themekeys">
    <Window.Resources>
        <!-- The following code does not work because the ThemeName property (defined in regular theme keys) 
        is omitted in lightweight themes: -->
        <SolidColorBrush x:Key="{dxrt:BackstageThemeKey ResourceKey=Foreground, ThemeName=Office2019Colorful}" 
                         Color="Red"/>
        <SolidColorBrush x:Key="{dxrt:BackstageThemeKey ResourceKey=Foreground, ThemeName=Office2019Black}" 
                         Color="Blue"/>
    </Window.Resources>
</Window>

Usage Notes

  • WPF Theme Designer is not supported.
  • Lightweight themes do not have touch versions.
  • Lightweight themes are not applied at design time.
  • You cannot apply a lightweight theme to a single control, only to an entire application.

Footnotes

  1. Applies the Office2019HighContrast theme if the Windows High Contrast option is enabled.

See Also

Palettes

Modify Theme Resources