Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default styles do not apply to subclasses

Tags:

c#

wpf

xaml

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?

like image 371
sohum Avatar asked Dec 20 '22 05:12

sohum


1 Answers

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));
like image 86
AndrewS Avatar answered Jan 03 '23 17:01

AndrewS