I have an application that uses several custom themes that can be switched at runtime. The themes, the application and the UI (UserControls, dialogs etc.) each are in a separate .NET assembly.
The themes not only override the implicit default styles of controls (new control template), but also provide various explicit styles.
Example:
<!-- "Themes" assembly -->
<Style TargetType="Button" x:Key="DialogButtonStyle"
BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="24" />
<Setter Property="MinWidth" Value="86" />
<Setter Property="Padding" Value="8 0" />
</Style>
<!-- "UI" assembly -->
<Button Style="{DynamicResource DialogButtonStyle}"
Content="OK" />
Themes are applied by merging all their styles, brushes etc. into the application resources, e.g.:
<Application x:Class="GUIDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary x:Name="MainDictionary">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="ThemeDictionary">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes;component/SystemTheme.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
(Or corresponding code at runtime.)
Question:
Is it possible to define fallback styles in my UI assembly (not the application assembly)? These should be automatically applied if the application has not included any of the themes, i.e. when keys like "DialogButtonStyle" are undefined and cause error messages in the output.
What I want to achieve is that my UI library is fully themable, but can also be used without having to care about the custom themes.
What I tried:
(1) Define a dummy App.xaml that contains the fallback style. This works at design time (designer preview, code completion) but not at runtime.
(2) Define the styles in "Themes/Generic.xaml". This seems to work only for implicit styles, not explicit styles.
(3) Merge the Generic.xaml into the resources of all XAML files that use the style. This does not work because the style now overrides the theme.
Try to merge the fallback styles into your ResourceDictionary before you merge the theme resources:
Then the theme resources - if any - should override the fallback resources.
There is no way for the application to be able to apply these fallback resources unless you merge them into your application. If the application fails to apply any resource dictionary from the external assembly you will get runtime exceptions if you try to reference any of these resources in your views. The resources must be explicitly merged into the application somehow.