1

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.

Fildor
  • 14,510
  • 4
  • 35
  • 67

1 Answers1

3

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.

Fildor
  • 14,510
  • 4
  • 35
  • 67
  • So nice :) Which assembly is ThemeKeyExtensionBase? – jamesnet214 Jun 21 '21 at 11:00
  • @james.lee I am no longer on that project and even switched employers since. And we are not using DevExpress currently, so I cannot tell, at the moment. And I don't remember from the top of my head, I am afraid. – Fildor Jun 21 '21 at 11:15
  • This may be a good starting point for research: https://supportcenter.devexpress.com/ticket/details/k18542/how-to-implement-the-thememananger-theme-support-in-custom-controls – Fildor Jun 21 '21 at 11:26