Skip to main content
All docs
V25.1
  • Lightweight Themes

    • 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.1 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.
    using DevExpress.Xpf.Core;
    // ...
    public partial class App : Application {
        static App() {
            CompatibilitySettings.UseLightweightThemes = true;
            ApplicationThemeHelper.ApplicationThemeName = LightweightTheme.Win11Dark.Name;
        }
    }
    

    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:

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

    Theme List

    Windows 11 Themes

    Windows 10 Themes

    Office 2019 Themes

    Visual Studio 2019 Themes

    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:

    <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:

    <!-- 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.

    <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:

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

    Alternatively, you can create a LWThemeValueExtension descendant:

    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();
        }
    }
    

    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:

    <!-- 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:

    ApplicationThemeHelper.ApplicationThemeName = LightweightTheme.VS2019DarkDeepSea.Name;
    

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

    Lightweight Themes - Predefined Palettes

    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.

      To find the required color name, review lightweight theme resources available in the following folder: C:\Program Files\DevExpress 25.1\Components\Sources\XPF\DevExpress.Xpf.Themes\ThemesLW\Common.

    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.

    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);
    }
    

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

    Lightweight Themes - Custom Theme

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

    Lightweight Themes - Custom Palette Theme

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

    Property Description
    ShowInThemeSelector Specifies whether to display the theme in the theme/palette selector.
    DisplayCategory Specifies the theme category name.
    DisplayName Specifies the theme name in the theme selector.
    PaletteName Specifies the palette theme name in the palette selector.
    SmallGlyph Gets or sets the theme’s small icon.
    LargeGlyph Gets or sets the theme’s large icon.
    SvgGlyph Gets or sets the theme’s SVG icon.
    SvgPalette Gets 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.

    <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:

    <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:

    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;
        }
    }
    

    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:

      <Window ...
              xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys">
          <Button Background="{DynamicResource {dxgt:LWKey GridControl.Foreground}}"/>
      
    • Add your custom colors to the LightweightTheme.Palette resource dictionary:

      public partial class App : Application {
          public App() {
              CompatibilitySettings.UseLightweightThemes = true;
          }
          protected override void OnStartup(StartupEventArgs e) {
              var customPalette = new Dictionary<string, Color> {
                  {"Foreground", (Color)ColorConverter.ConvertFromString("#FFFF7200")},
                  {"SelectionBackground", Colors.Orange}
              };
              var customTheme = LightweightTheme.OverridePalette(LightweightTheme.Win10Dark, "CustomTheme", "Custom Theme", customPalette);
              customTheme.Palette.Add(new PaletteBrushThemeKeyExtension() { ResourceKey = "myForegroundKey" }, 
                                      new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFF7200"))
              );
              LightweightThemeManager.RegisterTheme(customTheme);
              ApplicationThemeHelper.ApplicationThemeName = customTheme.Name;
              base.OnStartup(e);
          }
      }
      
      <Window ...
              xmlns:dxt="http://schemas.devexpress.com/winfx/2008/xaml/core/themekeys">
          <Button Background="{DynamicResource {dxt:PaletteBrushThemeKey ResourceKey=myForegroundKey}}"/>
      

    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:

    <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:

    <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):

    <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