5

I have a weird scenario involving overriding default styles in WPF and having them apply to subclasses. Is this not possible? For example, I have the following code:

<Window x:Class="TestWPFStyling.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:testWpfStyling="clr-namespace:TestWPFStyling"
        Title="MainWindow" Height="350" Width="525" Background="White">
    <Window.Resources>
        <Style TargetType="testWpfStyling:SomeLabel">
            <Setter Property="Foreground" Value="Red" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <testWpfStyling:SomeLabel Grid.Row="0">This should be red.</testWpfStyling:SomeLabel>
        <testWpfStyling:YellowLabel Grid.Row="1">This should be red.</testWpfStyling:YellowLabel>
        <StackPanel Grid.Row="2">
            <StackPanel.Resources>
                <Style TargetType="testWpfStyling:SomeLabel">
                    <Setter Property="Foreground" Value="Blue" />
                </Style>
            </StackPanel.Resources>
            <testWpfStyling:SomeLabel>This should be blue.</testWpfStyling:SomeLabel>
            <testWpfStyling:YellowLabel>This should be blue.</testWpfStyling:YellowLabel>
        </StackPanel>

    </Grid>
</Window>

With this code-behind:

namespace TestWPFStyling
{
    public partial class MainWindow : Window
    {
    }

    public class SomeLabel : Label
    {
    }

    public class YellowLabel : SomeLabel
    {
    }
}

I would expect the control YellowLabel in the StackPanel to have a color of Blue and the one outside to be red, however both of them are black. Is there a way for a subclass to take on the default style of its parent?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
sohum
  • 3,207
  • 2
  • 39
  • 63
  • You don't normally subclass WPF UI elements. That being said, you need to `DefaultStyleKeyProperty.OverrideMetadata()`. Google it. – Federico Berasategui May 21 '13 at 19:00
  • A default style is applied only to the elements of exact TargetType, there is nothing you can do about it. Try overriding the default style for `SomeLabel` as HighCore suggested and the 'YellowLabel' will inherit the same style. – Novitchi S May 21 '13 at 19:06

1 Answers1

12

Actually this is how WPF works. I have a blog post that discusses WPF styling (primarily with regards to how our Theme property works) but the underlying issue for scenario 1 of problem 1 is the same as what you are describing. That is, that implicit local styles are located using the actual class type and have no relation to the DefaultStyleKey. The DefaultStyleKey is only used when locating the default style (i.e. the style that is applied to the control based on the current OS theme and the default generic.xaml for the control). One easy way to address this would be to set the Style of your derived control (e.g in its ctor) to a DynamicResource reference to the base class' style. E.g.

this.SetResourceReference(StyleProperty, typeof(SomeLabel));
AndrewS
  • 6,054
  • 24
  • 31