David
David

Reputation: 51

How do I override style in a specific theme

I'm trying to override the default style of a base control (TextBox, ComboBox) in a theme-file. Like this:

in themes/classic.xaml

<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Background" Value="Black"/>
</Style>

in themes/Aero.NormalColor.xaml

<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Background" Value="Green"/>
</Style>

But this doesn't seem to work. I always get the defaulted style with no changes. I even tried it with a specific key like

<Style x:Key="DefaultTextBoxStyle" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Background" Value="Green"/>
</Style>

and always use this key when declaring the control in xaml. Nothing seems to work.

If I put the style in the application.xaml file I have no problem but I want this style to be theme dependent. By the way, it works well with my own usercontrols.

Can someone tell me what I'm doing wrong here?

I know one solution could be to use a class to see wich theme I use and to use a trigger of somesort, but I really wanted to do this in xaml.

Thanks

Upvotes: 5

Views: 3067

Answers (3)

Geert van Horrik
Geert van Horrik

Reputation: 5724

The problem is that you are getting circular references. This is because you define a style with class XXX, but also use the same resource as base resource.

I have wrote a blog article about this a "long" time ago, it explains what to do:

http://blog.catenalogic.com/post/2009/07/20/Override-or-customize-WPF-themes-such-as-PresentationFrameworkAero.aspx

The trick is to define a style in the same resource dictionary with the key "DefaultTextBoxStyle", and then programatically add the styles with the right key ("{x:Type TextBox}" the to main application resource. This way, you avoid the circular references.

Upvotes: 1

Rick Sladkey
Rick Sladkey

Reputation: 34250

Unfortunately, the ThemeInfo mechanism is only used for controls defined in the same assembly. What you want is to load theme-specific resources for controls that are not your own. I haven't tested it but I think what you need is the ThemeDictionary Markup Extension. A ThemeDictionary loads a theme-appropriate ResourceDictionary from an assembly.

Here is someone who go it to work statically, which appears to be what you want.

Upvotes: 1

brunnerh
brunnerh

Reputation: 185445

Did you reference your theme somewhere? e.g.

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="Test.App">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Simple Styles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Also, don't use the x:Key in themes unless it's just a sub-style that is referenced inside the theme by another style.

Upvotes: 1

Related Questions