I am in the process of creating a base window class for most of my windows to derive from. Obviously the best solution for this was a separate class, and a style that applies to it.
The issue is that the <Style ../>
I have is not being applied when it is in App.Resources
. That is, if it's defined in an external ResourceDictionary
, and merged into App.xaml
's resources, or a local dictionary and merged, or placed inline into App.Resources
. The <Style ../>
is, however, applied when it is placed into Themes/Generic.xaml
.
The problem can be demonstrated without doing anything special at all in the base window, apart from overriding the DefaultStyleKeyProperty
.
Below is ThemeWindow
:
public class ThemeWindow : Window
{
static ThemeWindow()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ThemeWindow), new FrameworkPropertyMetadata(typeof(ThemeWindow)));
}
}
Here is the very simple <Style ../>
I am trying to apply (it makes the Window
background red, nothing more):
<Style TargetType="{x:Type testing:ThemeWindow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type testing:ThemeWindow}">
<Grid>
<Grid.Background>
<SolidColorBrush Color="Red"/>
</Grid.Background>
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The MainWindow
that uses ThemeWindow
, is simply the following XAML:
<testing:ThemeWindow x:Class="Testing.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:testing="clr-namespace:Testing"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="125,83,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
</testing:ThemeWindow>
Now, as stated, if you place that Style
in its own ResourceDictionary
, and include it like this:
<App.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/ThemeWindow.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</App.Resources>
.. it does not work. If you inline the style straight into App.Resources
, it does not work.
The only situation I can find it working is to call the ResourceDictionary
xaml Generic.xaml
, and place it into the Themes/
directory of the application.
I am wondering exactly why this is happening.
My only theory is that when WPF sees a control type, it will head over to Themes
, and scan all ResourceDictionary
s for the type, then fall back to Generic.xaml
and load it. This doesn't explain why it would not load if the <Style />
is available in a merged ResourceDictionary
though. Note that it does work if the MergedDictionary
is placed into Generic.xaml
, for obvious reasons.
I'm perfectly fine with having to merge the ResourceDictionary
into Generic.xaml
if that's what I have to do. I just want to get down at the technical details as to why it needs to be like this.
Screenshots of this not working / working: