XAML 101: Getting Started with Styles

FacebookTwitterGoogle+Share

Source code for this sample on GitHub: https://github.com/billreiss/xamlnative/tree/master/Xaml101/012_Styles

So far we have seen ThemeResources and also created our own Resources that we can then use with the StaticResource markup extension. We can mix and match these to customize any element in our XAML.

Consider the XAML from the last post:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.Resources>
        <SolidColorBrush x:Key="redBrush" Color="Red"/>
    </Grid.Resources>
    <StackPanel>
        <TextBlock Text="Here is some text" Foreground="{StaticResource redBrush}"/>
        <TextBlock Text="Some more text" Foreground="{StaticResource redBrush}"/>
        <TextBlock Text="3rd line of text" Foreground="{StaticResource redBrush}"/>
    </StackPanel>
</Grid>

Let’s add the use of a built in themed resource to set the font size. Select the first TextBlock, and then in the Properties pane (I like to Arrange by Name, I think it’s easier to find things that way) look for the FontSize property. It should be showing a value of 15, the default font size for a TextBlock. Click the little “peg” next to it.

image

This brings up a menu with a few options. Pick System Resource then TextStyleExtraLargeFontSize. The XAML should now look like this:

<TextBlock Text="Here is some text" Foreground="{StaticResource redBrush}" FontSize="{ThemeResource TextStyleExtraLargeFontSize}"/>

You can copy and paste this FontSize property to the other TextBlocks, or set each the same way we set the first one.

Now we have some large red text.

image

Now it’s right up against the edge, so let’s add a Margin to each TextBlock:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.Resources>
            <SolidColorBrush x:Key="redBrush" Color="Red"/>
        </Grid.Resources>
        <StackPanel>
            <TextBlock Text="Here is some text" 
                       Margin="10,0,10,0" 
                       Foreground="{StaticResource redBrush}" 
                       FontSize="{ThemeResource TextStyleExtraLargeFontSize}"/>
            <TextBlock Text="Some more text" 
                       Margin="10,0,10,0" 
                       Foreground="{StaticResource redBrush}" 
                       FontSize="{ThemeResource TextStyleExtraLargeFontSize}"/>
            <TextBlock Text="3rd line of text" 
                       Margin="10,0,10,0" 
                       Foreground="{StaticResource redBrush}" 
                       FontSize="{ThemeResource TextStyleExtraLargeFontSize}"/>
        </StackPanel>
    </Grid>

Now it looks like this:

image

This is fine, and we are getting the results we want, but now we’re back to the fragility problem where we have to change things in multiple places if we want to change the design of the app. This is where Styles come in. You may be familiar with styles in HTML using CSS, and generally you can think about these the same way.

Styles in XAML allow you to specify values for multiple properties and apply them to a control. There are some other things you can do with styles too, and we will see those over time, but let’s get through the basics now.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.Resources>
        <SolidColorBrush x:Key="redBrush" Color="Red"/>
        <Style x:Key="redLargeTextStyle" TargetType="TextBlock">
            <Setter Property="Margin" Value="10,0,10,0"/>
            <Setter Property="Foreground" Value="{StaticResource redBrush}"/>
            <Setter Property="FontSize" Value="{ThemeResource TextStyleExtraLargeFontSize}"/>
        </Style>
    </Grid.Resources>
    <StackPanel>
        <TextBlock Text="Here is some text" Style="{StaticResource redLargeTextStyle}"/>
        <TextBlock Text="Some more text" Style="{StaticResource redLargeTextStyle}"/>
        <TextBlock Text="3rd line of text" Style="{StaticResource redLargeTextStyle}"/>
    </StackPanel>
</Grid>

This XAML defines a Resource of type Style, and gives it a key name so we can reference it where we want, and tells it what type of control this style applies to. The Style then contains a list of Setters with property names and values. We then set the Style property on each TextBlock to use the Style we defined as a Resource.

image

Things look just like they did before, but now if we want to change any of the property setter values, or add or remove style setters, we can do that all in one place and everywhere we use that style will be changed.

For example, if we want the text to be italic, we can add another setter to the Style:

<Style x:Key="redLargeTextStyle" TargetType="TextBlock">
    <Setter Property="Margin" Value="10,0,10,0"/>
    <Setter Property="Foreground" Value="{StaticResource redBrush}"/>
    <Setter Property="FontSize" Value="{ThemeResource TextStyleExtraLargeFontSize}"/>
    <Setter Property="FontStyle" Value="Italic"/>
</Style>

And then it looks like this:

image

You can override any property defined in the style by explicitly setting it on the control, like if we want the last line to be blue:

<TextBlock Foreground="Blue" Text="3rd line of text" Style="{StaticResource redLargeTextStyle}"/>

image

Now let’s say you wanted to have your style applied to all TextBlocks without setting the Style property on each of them. For this we can define an implicit style. This is easy enough to do, just don’t specify an x:Key value on your Style. Then this will be the default style for that type of control. Note that you can still override this by specifying a value for the Style property.