Thursday, December 7, 2017

Using Custom Resource in DevExpress WPF Theme

Leave a Comment

Objective:

I have a WPF project which shall be themed using DevExpress Themes. There is a Login-UserControl that shall have a themable background image.

Implementation

I made a custom Theme. In that theme I have a Folder "CustomResources" in which there is an Image, let's call it "Background.png" and a "Brushes.xaml" that defines an ImageBrush like this:

<ResourceDictionary ...>     <ImageBrush x:Key="{CustomThemeKeyAssembly:CustomThemeResourcesThemeKey ResourceKey=LoginBackgroundImageBrush, ThemeName=CustomTheme}" ImageSource="Background.png" /> </ResourceDictionary> 

Accordingly, I have a shared Assembly CustomThemeKeyAssembly that derives a Custom ResourceThemeKey.

In the Project, I register and set the Theme using ApplicationThemeHelper

var theme = new Theme("CustomTheme") {     AssemblyName = "DevExpress.Xpf.Themes.CustomTheme.v17.2" }; Theme.RegisterTheme(theme);  ApplicationThemeHelper.ApplicationThemeName = "CustomTheme"; 

and I reference the Resource through

Background="{dxci:ThemeResource ThemeKey={CustomThemeKeyAssembly:CustomThemeResourcesThemeKey ResourceKey=LoginBackgroundImageBrush}}" 

As advised by DevExpress Knowledgebase / Support.

Problem

The Resource is only found and displayed, if I add a Merged Resource Dictionary like this:

ResourceDictionary loginBackgroundDictionary = new ResourceDictionary {     Source = new Uri($"pack://application:,,,/{MyProject.Properties.Settings.Default.ThemeAssembly};Component/CustomResources/Brushes.xaml", UriKind.Absolute) };  //Add LoginBackgroundImageBrush Dictionary Resources.MergedDictionaries.Add(loginBackgroundDictionary); 

No article or example mentions having to do this, though. So my impression is that I either am doing something wrong or I am missing some simple step like merging the Brushes.xaml into some ResourceDictionary.

Without that snippet I get a warning that the resource could not be found.

Question

Has anybody an idea where I am going wrong or what I am missing to get this working without that last snippet?

FYI: I am using DevExpress 17.2.3 and the ResourceKey Assembly is targeted to .net Framework 4.0

EDIT

Meanwhile, I tried adding the Brushes.xaml to Themes/Generic.xaml in the theme assembly like this:

<ResourceDictionary.MergedDictionaries>     <dxt:ResourceDictionaryEx Source="/DevExpress.Xpf.Themes.Office2016WhiteSE.v17.2;component/Themes/ControlStyles.xaml" />     <dxt:ResourceDictionaryEx Source="/DevExpress.Xpf.Themes.Office2016WhiteSE.v17.2;component/CustomResources/Brushes.xaml" /> </ResourceDictionary.MergedDictionaries> 

It didn't make any difference. Same behavior as before.

1 Answers

Answers 1

Problem solved!

The problem was in the CustomThemeKeyAssembly

The wrong implementation was

public class CustomThemeResourcesThemeKey : ThemeKeyExtensionBase {     public override Assembly Assembly => TypeInTargetAssembly != null ? TypeInTargetAssembly.Assembly : GetType().Assembly; } 

The working implementation is

public class CustomThemeResourcesThemeKey : ThemeKeyExtensionBase<ThemeResourcesThemeKeys> { } 

The breaking difference is the override of the Assembly property. The default implementation makes it work. I did that because it was done so in an example. Support told me to stick with the default implementation and it worked.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment