Implicit Styles, Templates, Controls and FrameworkElements



    Even though I’ve been working with WPF for over 3 years, I’m still learning some of its idiosyncrasies. A discussion came up recently about whether implicit styles are applied to elements in a template. It turns out that the answer is, it depends on whether the element inherits from Control.


    Consider the following example. This example creates an implicit style for a Label and another implicit style for a TextBlock. Then it defines a ControlTemplate for a Control, in which is a Label and TextBlock. Finally, the example adds a Control, TextBlock, and Label to the StackPanel. So this XAML displays a TextBlock and Label, which are part of the Control, and another TextBlock and Label, which are not part of the Control.


    <StackPanel>


      <StackPanel.Resources>


        <Style TargetType=”Label”>
          <Setter Property=”Foreground” Value=”Red”/>
        </Style>
        <Style TargetType=”TextBlock”>
          <Setter Property=”Foreground” Value=”Red”/>
        </Style>


        <Style TargetType=”Control”>
          <Setter Property=”Template”>
            <Setter.Value>
              <ControlTemplate>
                <StackPanel Background=”Beige”>
                  <TextBlock>TextBlock Inside Control</TextBlock>
                  <Label>Label Inside Control</Label>
                </StackPanel>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </StackPanel.Resources>


      <Control/>
      <TextBlock Text=”TextBlock outside control”/>
      <Label Content=”Label outside control”/>


    </StackPanel>


    Here is a rendering of the XAML:


    clip_image001


    Surprised? So was I. Apparently, people have been mystified by this for a while. It turns out that implicit styles are applied to elements in templates if the element inherits from Control, but not if the element doesn’t inherit from Control. Why? The reason I was given is that Controls are more obvious than elements, and it’s likely that an implicit style for a control should be applied everywhere, where it is less likely that a implicit style for an element should be universally applied. There’s a legitimate point to this argument. Consider the following:


    <StackPanel>
      <StackPanel.Resources>
        <Style TargetType=”TextBlock”>
          <Setter Property=”FontSize” Value=”16″/>
          <Setter Property=”Foreground” Value=”Green”/>
        </Style>


      </StackPanel.Resources>


      <TextBlock HorizontalAlignment=”Center” Text=”Hello!”/>
      <Button Content=”Click me!” Width=”200″/>
      <TextBlock HorizontalAlignment=”Center” Text=”Please click the button”/>
    </StackPanel>


    A Button displays strings by eventually creating a TextBlock and adding the string to the TextBlock. If the TextBlock in the Button used implicit styles defined by the application, the XAML would render this way:


    clip_image002


    That probably isn’t the behavior you want. On the other hand, suppose you’re creating a cool UI and you want all of your RepeatButtons to have a specific look. If you define the appearance of the RepeatButton once, all RepeatButtons will use have that appearance, even if the RepeatButton is inside a ControlTemplate.


    So if you ever run into seemingly inconsistent behavior and wonder what’s going on, now you know. If you’ve run into this and understood what the difference is and wondered why in the world it was designed this way, hopefully this has given you a little bit of insight.

Comments (1)

  1. cplotts says:

    Great article. I just was stumped by this … and I've been working with WPF for almost 4 years!

    One point of clarity. In your last example, if you stick the style for the TextBlock into the Application resources … the text inside the Button __DOES__ style green. If the style is in the StackPanel Resources section (as you have it), the TextBlock styles black … as you would expect after reading this post.

    Can you explain that behavior?

    It seems like sticking implicit Styles for elements … into the Application resources, says … 'Yes, I do want to style even elements inside of templates.'