简体   繁体   中英

WPF: Applying a custom theme (skin) to a custom control

I have an application set up so that I can adjust its skin at run time. I am doing it as follows each time I change the skin:

Uri uri = new Uri("SomeThemeAssembly;component/Themes/StandardTheme.xaml", UriKind.Relative)
Application.Current.Resources.MergedDictionaries.Clear();
ResourceDictionary resource = (ResourceDictionary)Application.LoadComponent(uri);
Application.Current.Resources.MergedDictionaries.Add(resource);

This works fine.

I have also created a custom control with its controltemplate defined in Themes/Generic.xaml using ComponentResourceKeys for the relevant resources, etc

x:Key="{ComponentResourceKey 
TypeInTargetAssembly={x:Type local:MyCustomControl}, 
ResourceId=MyBrush}"

The style of the custom control itself doesnt use a componentresourcekey as I want it to style all instances.

<Style TargetType="{x:Type local:MyCustomControl}">

Again this all works fine and standard controls I have used to compose elements of my custom control are appropriately styled when I change the skin.

However there are a number of custom properties( brushes, widths, etc) on my control that need to be styled to fit in with the skins I am applying.

In examples I have seen using the standard windows themes adding an additional file

Luna.StandardColor.Xaml

for example, to the themes directory of the custom control allows a modified control template to be set and picked up when that particular theme is applied. This won't work for me, as far as I can tell anyway, as my skins are not themes.

Can something similar be achieved when using 'skins' in the manner I have?

Obviously I can add Styles and ControlTemplates to my skin assemblies but this feels wrong especially as there is a standard naming convention across the skin assemblies for resources. So only a single more maintainable style would be required if it could be stored in Themes/StandardTheme.xaml in my custom control's assembly.

Having tried to read around on this subject I have the impression want I want to do is either impossible or will require loads of extra leg work.

Any thoughts appreciated.

In the CustomControls Themes Directory add a MyNewTheme.xaml file that's a resource dictionary that has an implicit style set for your control. Then merge that resource dictionary in with your other one as needed. For example:

Uri uri = new Uri("SomeThemeAssembly;component/Themes/MyNewTheme.xaml", UriKind.Relative)
Uri controlsUri = new Uri("ControlAssembly;component/Themes/MyNewTheme.xaml", UriKind.Relative)
Application.Current.Resources.MergedDictionaries.Clear();
ResourceDictionary resource = (ResourceDictionary)Application.LoadComponent(uri);
Application.Current.Resources.MergedDictionaries.Add(resource);
ResourceDictionary resource = (ResourceDictionary)Application.LoadComponent(controlsUri);
Application.Current.Resources.MergedDictionaries.Add(resource);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM