programming4us
programming4us
MULTIMEDIA

Silverlight Recipes : Managing XAML Resources

- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire
7/13/2011 6:10:01 PM

1. Problem

You want to create a consistent UI without having to replicate styles, colors, templates, and so forth on individual elements, much in the same way that CSS resources are shared in a web application.

2. Solution

Take advantage of ResourceDictionary objects to store resources that can be accessed using the StaticResource markup extension. The Resources member introduced in the FrameworkElement class is of type ResourceDictionary, which is a Dictionary collection accessible via name/value pairs. The Resources member can be used to organize common styles, brushes, and colors for use across an application.

3. How It Works

A markup extension provides additional evaluation for a value set on an attribute in XAML. For example, a value can be configured for Background equal to the string "Green", which is evaluated by a TypeConverter that takes the string value and converts it to the Colors.Green enumerations value. You can also set Background equal to the hexadecimal value, such as #FF008000, which also equals the color Green.

Type converters are great for single string values converted to a particular type. A markup extension, such as StaticResource, allows more complex string values that consist of multiple types to be evaluated or substituted for the placeholder value of an attribute. A StaticResource value can be configured for any XAML property attribute except for event attributes. All markup extensions have the following syntax:

<element attribute="{MarkupExtensionName Value}" />

When you first see this syntax, it looks a bit confusing, but once you understand it, you see the power that markup extensions provide. For the StaticResource markup extension, Value represents an x:key name for a resource located in a Resources collection in the application. Usually resources are located at the Application or UserControl (page) level, but they can be located on any element that inherits from FrameworkElement, such as Grid or StackPanel objects.

Silverlight 4 added the ability to have a merged resource dictionary, which means that you can place the contents of a resource dictionary in a separate file but have the resources treated as a logical part of the main XAML file. Resources stored in a merged resource dictionary are accesses only after all resources in the main XAML code file are checked for a match. The MergedDictionaries is a collection the UIElement.ResourceDictionary object. Here is an example:

<ResourceDictionary>
<SolidColorBrush Color="#FFFFFFFF" x:Key="darkBrush"/>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/GradientsResourceDictionary.xaml">
<ResourceDictionary Source="/StylesResourceDictionary.xaml">
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

The separate resource dictionary files contain a <ResourceDictionary> declaration as the root element with the resources identified as if part of the MainPage.ResourceDictonary directly.

4. The Code

The sample application for this recipe includes a number of resources defined in the MainPage class. Here is an example resource defined at the <UserControl> level:

<UserControl.Resources>
<Color x:Key="Pumpkin">#FFD5901F</Color>
<Color x:Key="Lime">#FF75E564</Color>
<LinearGradientBrush x:Key="PumpkinLimeBrush"
EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{StaticResource Lime}"/>
<GradientStop Color="{StaticResource Pumpkin}" Offset="1"/>
</LinearGradientBrush>
</UserControl.Resources>

Three resources are defined with two color resources and a brush resource. The brush is a LinearGradientBrush that references the color resources for the GradientStop Color value using the syntax discussed earlier:

{StaticResource Lime}

NOTE

For performance reasons, if a resource consists of other resources, define the resources in order of dependency as shown in the preceding example so that forward references can be avoided.

Notice that every resource has a name defined by the x:Key attribute, which is different than the x:Name attribute used to name XAML elements. This is the value used to reference a resource with the XAML on the page. For example, you add a StackPanel to Grid.Row="0" and Grid.Column="0" and configure the Background attribute to this value:

Background="{StaticResource PumpkinLimeBrush}"

Figure 1 shows the result.

Figure 1. Applying the PumpkinLimeBrush resource to a StackPanel

Expression Blend 4 provides great support to create and manage resources. There is a Resources tab next to the Project and Properties tabs in the UI. You can expand the tree in the Resources tab to view resources created as part of the available objects, such as the Application, MainPage, and StackPanel levels, as shown in Figure 2.

Figure 2. The Resources tab in Expression Blend 4

Expression Blend 4 provides a drop-down editor for modifying resources right on the Resources tab, as shown in Figure 3.

Figure 3. In-place editing in the Resources tab

Resources can be defined deeper in the XAML tree, such as on a Grid or StackPanel control, or even on a Rectangle directly. Any object that inherits from FrameworkElement has the Resources collection. Click the Advanced Properties Option button next to Background, and select Convert to New Resource in the pop-up menu in Expression Blend 4, as shown in Figure 4. The Create Brush Resource dialog displays the two available options to store a resource; either at the application or page level, as shown in the Define In section of Figure 4.

Figure 4. Converting a brush to a resource

If you want to define a resource at a different level, you can use Expression Blend 4 to create a resource at the document or UserControl level and then copy it to the location where you want it. As an example, define a new brush called FallBrush at the UserControl level and then move it to a new location, in this case a StackPanel, using the following code:

<StackPanel Grid.Column="0" Grid.Row="1" Margin="2,2,2,2">
<StackPanel.Resources>
<LinearGradientBrush x:Key="FallBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000000"/>
<GradientStop Color="#FFFFA500" Offset="1"/>
</LinearGradientBrush>
</StackPanel.Resources><Rectangle Margin="2,2,2,2" Stroke="#FF000000"
Fill="{StaticResource FallBrush}" Height="193"/>
</StackPanel>


You've moved the FallBrush resource from the UserControl.Resources to StackPanel.Resources and applied it to a Rectangle, resulting in the UI as shown in Figure 1 above. This limits use of the resource within the StackPanel only. For resources that need to be shared across the application, locate the resource at the page or application level.

For this recipe, all of the modifications are in the XAML, shown in Listing 1.

Listing 1. Recipe 9's MainPage.xaml File
<UserControl x:Class="Ch02_ProgrammingModel.Recipe2_9.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="300"
d:DesignWidth="400"> <UserControl.Resources>
<Color x:Key="Pumpkin">#FFD5901F</Color>
<Color x:Key="Lime">#FF75E564</Color>
<LinearGradientBrush x:Key="PumpkinLimeBrush"
EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{StaticResource Lime}"/>
<GradientStop Color="{StaticResource Pumpkin}" Offset="1"/>
</LinearGradientBrush>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"/>
<RowDefinition Height="0.5*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Background=
"{StaticResource PumpkinLimeBrush}" Margin="2,2,2,2">
</StackPanel>
<StackPanel Grid.Row="1" Margin="2,2,2,2">

<StackPanel.Resources>
<LinearGradientBrush x:Key="FallBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000000"/>
<GradientStop Color="#FFFFA500" Offset="1"/>
</LinearGradientBrush>
</StackPanel.Resources>
<Rectangle Margin="2,2,2,2" Stroke="#FF000000" Fill=
"{StaticResource FallBrush}" Height="193"/>
</StackPanel>
</Grid>
</UserControl>

Other  
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us
programming4us
 
 
programming4us