...">

WPF Override Style in Unified Dictionary

In my word file I have

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

      

In my xaml Window file I have

    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/XXX;component/XXX.xaml"/>
            </ResourceDictionary.MergedDictionaries>

            <Style TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
                <Setter Property="FontSize" Value="20"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
            </Style>
        </ResourceDictionary>
    </Window.Resources>

      

In the designer, I can see that the label has a black background and a white foreground, but at runtime it has a black foreground and a transparent background by default. It is very obvious that I want to inherit the dictionary style and it doesn't work. What was I doing there? I am using VS 2013 and .NET 4.5

Edit: If I remove the style inside Windows.Resources then the dictionary style is applied. If I translate the style from Windows Resource to StackPanel.Resource which contains some labels then inheritance works fine

+3


source to share


1 answer


According to MSDN, Mergeable Resource Dictionaries :

If a key is defined in the primary dictionary and also in a dictionary that was merged, then the resource that is returned will come from the primary dictionary.

According to this rule, your second style will be found first. This style is then referenced to the style with the same key {x:Type Label}

. For some reason this allows it null

. However, checking the first style shows that the BasedOn reference has been resolved by default as expected. The same thing happens when the same explicit key is specified in both styles. However, everything works as expected when given different keys.

I am assuming the second style shades the first. The BasedOn reference may have been resolved by the style itself, but to prevent circular dependencies it sets it to null instead.



Personally, I would use explicit keys. For styles that need to be applied to all elements of a certain type, but in some cases need to be overridden, I would split things into two styles:

// The actual style, with all its setters, is given a descriptive name:
<Style x:Key="DescriptiveName" TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
    // Setters go here
</Style>

// A 'dummy' style that references the above style.
// Its sole purpose is to apply the style to all elements of the target type.
<Style TargetType="Label" BasedOn="{StaticResource DescriptiveName}" />

      

Whenever you need to override a style, you can refer to it unambiguously by name:

<Style TargetType="Label" BasedOn="{StaticResource DescriptiveName}">
    // Overriding setters go here
</Style>

      

+5


source







All Articles