Wpf – Styles from generic.xaml are not applied

generic.xamlstylesthemeswpf

I made a class library assembly in which I created custom controls, and I defined the default styles in the generic.xaml file.

It seems this is a quite common problem, as long as many people are posting about it.
However I couldn't find any useful answer for my case.

  • the generic.xaml is in the Themes folder.
  • the generix.xaml file Build Action is set to Page.
  • the ThemeInfo is properly defined in my AssemblyInfo.cs.

In my test application, if I manually merge the generic.xaml file from my custom controls assembly into the application App.xaml file like this:

<Application.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="/MyControlsAssembly;component/Themes/generic.xaml"/>
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Application.Resources>

then the custom controls are properly themed, but if I do not manually merge the generic.xaml, the controls appear with the default Windows theme.

Could you please tell me what am I forgetting and/or doing wrong ?

Additional info:

  • My ThemeInfo assembly attribute is defined as follow:

    [assembly: ThemeInfo(ResourceDictionaryLocation.SourceAssembly, ResourceDictionaryLocation.SourceAssembly)]

    (Note: the result is just the same with any combination of parameters for the ThemeInfo attribute)

  • There are two others .xaml files beside the generic.xaml file in the Themes folder.

  • There is a subfolder in the Themes folder that itself contains another .xaml file.

Best Answer

You need the following line in your custom control constructor:

public class MyCustomControl : Control
{
    static MyCustomControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
    }
}

Then if you have a generic.xaml file inside themes folder, with the following sample style:

<Style TargetType="{x:Type local:MyCustomControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyCustomControl}">
                <Border>
                    <Label>Testing...</Label>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Now the style will get automatically applied without any extra merging.

Related Topic