XAML 101: Creating your own Resources

FacebookTwitterGoogle+Share

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

A couple of posts ago, we looked at Themes and how you can use them to specify colors and other properties that would change with the currently selected theme. This was done through resource dictionaries, resource definitions and the ThemeResource markup extension.

The ThemeResources are used for consistency, but you may have consistency you want to enforce in your app to enforce the unique style of your app. Consider the following:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel>
        <TextBlock Text="Here is some text" Foreground="Red"/>
        <TextBlock Text="Some more text" Foreground="Red"/>
        <TextBlock Text="3rd line of text" Foreground="Red"/>
    </StackPanel>
</Grid>

And this is how it looks:

image

All the TextBlocks have a Foreground of Red, and this is fine and consistent, but if we wanted to change the foreground color, this is pretty fragile because we would need to change it in 3 places, and as the app grows, we would need to change it more.

A better way is to define a resource:

<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>

The StaticResource markup extension will look for any resources with a matching x:Key in any parent element, or in an application-wide resource definition. If we want the resource definition to apply to the whole page,  then the resource definition can be at the page level:

<Page
    x:Class="HelloXaml.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloXaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.Resources>
        <SolidColorBrush x:Key="redBrush" Color="Red"/>
    </Page.Resources>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <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>
</Page>

The most common case is probably that you would want this resource definition to be available anywhere in your app. To do this you can make the definition in your App.xaml file:

<Application
    x:Class="HelloXaml.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloXaml"
    RequestedTheme="Light">
    <Application.Resources>
        <SolidColorBrush x:Key="redBrush" Color="Red"/>
    </Application.Resources>
</Application>