Sebastien ROBERT
Sebastien ROBERT

Reputation: 636

Styles from generic.xaml are not applied

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.

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:

Upvotes: 25

Views: 17024

Answers (5)

Artem
Artem

Reputation: 487

In My case I forget to remove the x:Key from <Style> tag.

Wrong:

<Style TargetType="controls:IpTextBox" x:Key="MyControlStyle">

Correct:

<Style TargetType="controls:IpTextBox">

Upvotes: 1

Jorbr
Jorbr

Reputation: 11

I was having the same problem due to the following attribute in the custom control assembly:

[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]

Changing UltimateResourceFallbackLocation.Satellite to UltimateResourceFallbackLocation.MainAssembly or removing the second parameter completely fixed the problem for me (you can also remove the attribute if you do not need to define the neutral language of your assembly).

Upvotes: 0

MikeF
MikeF

Reputation: 51

Not sure if this works in WPF, but it works for me in Silverlight:

Constructor:

public class MyCustomControl : Control
{
    static MyCustomControl()
    {
        this.Style = (Style)Application.Current.Resources["MyCustomControlStyle"];
    }
}

Style:

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

Upvotes: 0

JT_
JT_

Reputation: 513

To apply default styles in Themes\Generic.xaml in my custom controls library I decided to seek inspiration from a well established open source controls library (MahApps). This project gives you a really good example of how to structure and layout a custom controls library.

Cut a long story short, to get your default styles in Themes\Generic.xaml you need to include the following in the AssemblyInfo.cs file in your custom controls library:

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

In my case, my custom controls AssemblyInfo.cs looked something like:

using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Markup;

[assembly: AssemblyCopyright("...")]
[assembly: ComVisible(false)]

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

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
[assembly: AssemblyTitleAttribute("...")]
[assembly: AssemblyDescriptionAttribute("")]
[assembly: AssemblyProductAttribute("...")]
[assembly: AssemblyCompany("...")]

Upvotes: 19

Eternal21
Eternal21

Reputation: 4664

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.

Upvotes: 14

Related Questions