DotNetRussell
DotNetRussell

Reputation: 9857

Unable to override default style of wpf control in generic.xaml

So we are trying to retemplate some stock wpf controls by changing their default styles in the generic.xaml

When we normally do this we subclass a control and then override the default style key of the subclassed control in its static initializer. However, we are trying to just override the basic control now without subclassing it. That way anyone in the company using the stock wpf control will get our new styling by default.

I can't seem to get this to work though.

In my sandbox application which is a watered down version of our actual problem, I have the following.

MainWindow.xaml

<StackPanel>
    <TextBlock>It doesn't work</TextBlock>
    <local:CustomTextBlock>It works</local:CustomTextBlock>
</StackPanel>

Themes/Generic.xaml

<Style TargetType="{x:Type TextBlock}">
    <Setter Property="FontSize" Value="100" />
</Style>


<Style TargetType="{x:Type test:CustomTextBlock}">
    <Setter Property="FontSize" Value="100" />
</Style>

CustomTextBlock.cs

public class CustomTextBlock : TextBlock
{
    static CustomTextBlock()
    {
        Type _CustomTextBlock = typeof(CustomTextBlock);
        DefaultStyleKeyProperty.OverrideMetadata(
            _CustomTextBlock,
            new FrameworkPropertyMetadata(_CustomTextBlock));
    }
}

Which results in this being displayed.

enter image description here

My theory is that the WPF engine is ignoring our style because the default style key is either A: not overridden or B: is finding their style in their generic.xaml first.

My question is, is there a work around for this? Are my assumptions correct?

UPDATE:

According to reference source, the default style key is overridden in the stock wpf control for TextBlock.cs in this case

Reference Source TextBlock.cs (Line 346)

Upvotes: 2

Views: 1827

Answers (2)

Shawn Kendrot
Shawn Kendrot

Reputation: 12465

To accomplish this, you can put your styles either directly into App.xaml or into a separate ResourceDictionary (named DefaultStyles.xaml).

Putting directly into App.xaml is easy enough, just put the style within the Resources element.

If you want to put the styles into a file (this is useful if you want the styles for multiple applications or within multiple assemblies) you add it to the MergedDictionaries of your App.xaml as such

<Application x:Class="MyAwesomeApp"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Themes/DefaultStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

This assumes that you put the file DefaultStyles into the Themes folder. If it is in another assembly you would do the following:

<ResourceDictionary Source="/Company.Controls.UI;component/DefaultStyles.xaml"/>

Upvotes: 3

J&#252;rgen R&#246;hr
J&#252;rgen R&#246;hr

Reputation: 941

Have a look at this post (What is so special about Generic.xaml).

The main issue seems to be:

WPF looks for the default style in a special resource dictionary in the Themes folder in the same assembly as the control.

'Your' control is defined in 'your' assembly, TextBlock is defined in PresentationFramework. So you better create another ResourceDictionary for re-styling standard controls and include/merge it in each of your xaml documents (I suppose, this hurts).

Hope it helps.

Upvotes: 1

Related Questions