5
votes

I have the following situation (simplified):

In my ResourceDictionary, I have defined a couple of named styles for Label:

<Style
    x:Key="sNormalLabel"
    TargetType="Label" >
    <Setter Property="FontFamily" Value="Verdana" />
    <Setter Property="FontSize" Value="12" />
    <!-- ... -->
</Style>
<Style
    x:Key="sHeaderLabel"
    TargetType="Label"
    BasedOn="{StaticResource sNormalLabel}" >
    <Setter Property="FontSize" Value="16" />
</Style>

And then I make one of them default by referencing it with BasedOn, in a style that doesn't have a key:

<!-- Apply Normal label automatically -->
<Style 
    TargetType="Label"
    BasedOn="{StaticResource sNormalLabel}" />

I thought it very convenient to apply the normal style of label automatically, that way I know that if in the future our design team decides to go with Wingdings or something, it is very easy to change for the entire application (in fact all applications that share the same ResourceDictionary).

Creating a UserControl I want to add a Label at the top with the sHeaderLabel style, so as it goes I apply

Style={StaticResource sHeaderLabel}

in the USerControl XAML, and all looks fine in the designer.

However, when I add the UserControl to the MainWindow, the header label goes back to the sNormalLabel style (the automatically applied one).

I assume it has to do with the order in which the styles are applied, the UserControl is styled by the MainWindow after it is created, and the sHeaderLabel style is overwritten by the automatic one.

This leaves me with a couple of unanswered questions:

  1. Is it uncommon and contrary to best-practice to use automatically applied styles as I have done? I thought it very practical, but maybe this is the wrong way to go.
  2. Is there any way to exclude certain controls explicitly from having these automatic styles applied? The only way I can think of is to extend Label with HeaderLabel and apply a different resource key, so that HeaderLabel automatically has sHeaderLabel style applied to it. Is there any other way?

If anyone has any practical experience with something similar, I would appreciate some pointers.

EDIT: Interestingly, I just realized that I only see these problems with the Font* properties. Setting Foreground/Background brushes differently in Normal/Header style leaves the Label in the UserControl (which is styled to sHeaderLabel) with the CORRECT color. Setting FontWeight to bold in sHeaderLabel has no effect however.

I have also set up TextBox styles in the same way, with a HeaderTExtBox style, and I don't see the problem there either, only with Labels.

Cheers!

./Fredrik

2
If you're excluding controls from applying styles, you probably shouldn't be applying the style to everything in the first place. While i'm not sure enough to provide an answer to the question, I tend to avoid automatic styles since they can sometimes unexpectedly mess with built-in DataTemplates containing these types. For example, if you don't know whether a button contains a Label or a TextBlock, you can't be sure how an auto style will effect it.Will Eddins
Hi Will, thanks for your response! The idea was to have commonly controls automatically conform to a pre-defined standard. I have set up the appearance of the Forms DataGridView WAAAY too many times to not love the idea of defining the standard once, and have it apply everywhere. Then all situations are different, and if I have to go in and override a style, or even exclude a particular control in some cases, I am more than happy to do so. But what you say about unexpected side-effects makes perfect sense! I am already seeing the Microsoft Ribbon control do things it didn't use to ..Fredrik

2 Answers

2
votes

A good practice may be to avoid applying base automatic styles to standard types, since the results can be unpredictable.

In response to what ended up being your issue, a good example is applying a style to TextBlock. This style is going to be applied to Label, Button, and any other control anywhere in the framework that may contain a TextBlock that isn't overriding the style you're setting.

You can't "un-apply" a style when applying them to all instances of a type, you can only override the style with a new style. Unless you can accurately predict everything in your application that this will effect (such as styling a control you made), you should avoid using the automatic style in favor of setting the x:Key.

0
votes

Well, I figured it out.

I also had a default style for TextBlock, and removing that was a global fix-all. According to MSDN, Label and TextBlock have no relation by inheritence, and TextBlock does not derive from Control, which is interesting.

Possibly Label uses TextBlock internally for rendering, I don't know that, but clearly the TextBlock default style was affecting the behavior of Label.