So far, we have covered topics that discuss how to build Silverlight applications. In this chapter we are going to put it aside for a bit and take a look at how to make our code look better and behave better. We will discuss how to utilize sample data while using binding, how to arrange styles in a smart way using resource dictionaries, how to localize an application, and finish off with how to handle events at the application level.
In this chapter we will cover the following topics:
When we discussed styles in Chapter 3, Enhancing the User Interface, we realized that styles can be placed in various scopes throughout our application. Most of the time we will place styles at the global level, which means our App.xaml
file may get messy quite fast. A commonly used strategy to enhance the App.xaml
file is to place styles and resources that are related to one another into what's called a resource dictionary. When an application uses multiple resource dictionaries, these dictionaries will be merged at compile time.
A nice feature of resource dictionaries is their ability to be used as hosts to sample data at design time.
When creating an application that uses a custom item template, it's easier to design the template when you can view the data you are designing it for. When you use the binding engine to bind data in Visual Studio, you are usually left in the cold. You can set the properties you bind to, but you can't see the result until you run the application. If you have made a mistake, you need to fix it, compile it, and run it again. This can get tedious quite fast. To get past this issue, sample data was introduced.
By using Microsoft Expression Blend, you can easily create sample data for your templates that will represent the real data you are binding and be viewed at design time.
Create a new Silverlight 4 project in Visual Studio 2010 and name it Chapter7-SampleData. Open MainPage.xaml
and add the following XAML code inside the LayoutRoot Grid
element:
<ListBox x:Name="ProductsList" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
Now that we have a ListBox
control added, let's add an item template to it. Perform the following steps:
The New Sample Data dialog box will pop up, as shown in the following screenshot:
Once the new data source is created, the Data window will show the current sample data collection. By default, we have a collection of two properties under the Collection section—Property1, which is a string and Property2, which is a Boolean:
To change a property's type, click on the little drop-down arrow beside it and change the type to either string, number, Boolean or image. Each type will have its own properties that you can set. For example, the image type will let you choose a directory with images to show, while the number type will let you set the length of the number. For our demonstration, keep Property1 a string but change the type of Property2 to image.
Now that we have the data structure all set up, let's set up the actual data. Click on the little icon next to Collection, which is the Edit Sample Values button. The following dialog box will appear:
The preceding dialog box allows us to set the number of records we wish to show and change the default form of the properties we have selected.
Leave the default settings and click on the OK button.
We have finished setting up all the sample data and it's time to use it with our ListBox
control. To add the sample data, simply click on Collection from the Data window and drag it to the ListBox
control. Your ListBox
control will now look as follows:
Take a look at the XAML code of MainPage.xaml
; you'll notice you have a new item template:
<DataTemplate x:Key="ItemTemplate"> <StackPanel> <TextBlock Text="{Binding Property1}"/> <Image Source="{Binding Property2}" HorizontalAlignment="Left" Height="64" Width="64"/> </StackPanel> </DataTemplate>
From here on, you can design your template just as discussed in the previous chapter. The difference now is that you have a visual representation of the data, which makes it easier to design your template.
If you are curious to see how the sample data is represented in code, take a look at the ProductsSampleData.xaml
file located in the ProductsSampleData
folder of the project. This is the file that got generated when you built your sample data using the GUI of Blend. The data from this file is bound to the elements of the item template of the ListBox
control.
Resource dictionaries are a concept of Silverlight that help you structure and reuse your resources, and styles into the Key
type dictionaries of objects. Dictionaries, just like styles, can exist at several positions in an application, such as page level or application level. By separating styles into external dictionaries, we can reuse these dictionaries in other projects by simply importing them into projects. Resource dictionaries are typically used for defining templates for custom-created controls (to create different themes for example, to be packed with the control) or storing animations and storyboards.
An example of a resource dictionary can look as follows:
<ResourceDictionary> <Style x:Key="MyButtonStyle" TargetType="Button"> <Setter Property="Background" Value="DarkRed"/> <Setter Property="Foreground" Value="#ff000000"/> <Setter Property="Padding" Value="13"/> <Setter Property="BorderThickness" Value="1"/> </Style> <Style x:Key="MyButtonStyle2" TargetType="Button" BasedOn="{StaticResource MyButtonStyle}"> <Setter Property="Margin" Value="10"/> <Setter Property="Background" Value="DarkBlue"/> <Setter Property="FontSize" Value="15"/> </Style> </ResourceDictionary>
The preceding resource dictionary holds two styles for Button
elements in our application. If we wish to use one of the styles for a button in the application, we will use the following syntax:
<Button Content="I'm styled!" Style="{StaticResource MyButtonStyle}"/>
When applying the preceding styles to two buttons, the result will be as follows:
Another use for resource dictionaries is when you style a control template. A template for a control you style might need to appear in more than one project, so it's a good idea to save it in a resource dictionary. Expression Blend makes it easy for us to save a style in a resource dictionary. Open the Chapter7-RD project in Expression Blend 4. The project contains a single Button
control, which we wish to template. Right-click on the Button
control and choose Edit Template and then Edit a Copy.... The Create Style Resource dialog will pop up, as shown in the following screenshot:
As can be seen from the preceding screenshot, the Resource dictionary option is grayed out. This is because we don't have any dictionary added to our project. Click on the New... button next to the grayed-out Resource dictionary drop-down box. Name the new dictionary MyButtonDictionary.xaml and click on OK. Blend will automatically switch to the resource dictionary editing pane and you can now edit the template of the button visually in Blend.
It's important to notice that Blend actually created a new XAML file in our project—the MyButtonDictionary.xaml
file we specified earlier. Under that file, we have all the styles we specified in Blend. If you open the file in Visual Studio 2010, you'll see this file is nothing more than a XAML file filled with styles, pretty similar to the App.xaml
file we have discussed earlier.
In order to use the resource dictionary, Silverlight will use a feature known as "Merged Resource Dictionaries". The Merged Resource Dictionaries feature provides a way to split up resources into separate files and merge them together for use in an application.
Open the App.xaml
file of our application in Visual Studio 2010, and you should see the following XAML code:
<Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="MyButtonDictionary.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources>
The application-level resources (Application.Resources
) node contains a single ResourceDictionary
element. Inside that node, we use the attached property—MergedDictionaries
to define a collection of resource dictionaries. The fact that these resource dictionaries are in different files helps us reuse our styles and have a clean and easy-to-read App.xaml
file.
It is also possible to add a resource dictionary that resides in a completely separate assembly (DLL) file. To add an external dictionary, first add a reference to the assembly file the dictionary resides in and then use the following syntax in your App.xaml
file under the ResourceDictionary
node:
<ResourceDictionary Source="/<your assembly>;component/<your dictionary>.xaml" />
Replace<your assembly>
with the name of your assembly file (that is ExternalDictionary)
and<your dictionary>
with the name of the dictionary file (that is TextStylesResources.xaml)
. If the dictionary file resides inside a folder, don't forget to add it as well!
In Chapter 3, Enhancing the User Interface, we have discussed the styles hierarchy and it's important to note that there is a hierarchy within the ResourceDictionary
node as well. If you add a resource dictionary and decide to override one of its styles, add the desired Style
node after the closing ResourceDictionary.MergedDictionaries
element. By doing this, you are overriding any style with the same key that is presented in any of the resource dictionaries you added. Just the same, any ResourceDictionary
element you add to the MergedDictionaries
node will override a style with the same key that is defined in a previous dictionary under the same MergedDictionaries
node.
Creating a resource dictionary doesn't have to involve Expression Blend. Creating a dictionary in Visual Studio 2010 is as easy as right-clicking on the project, choosing Add | New Item, and then selecting Silverlight Resource Dictionary. For our example, follow the steps to create a new dictionary and name it MyNewResourceDictionary.xaml
.
In order to actually use the dictionary within our application, add a new ResourceDictionary
element to the MergedDictionaries
collection in the App.xaml
file specifying our new dictionary as follows:
<ResourceDictionary Source="MyNewResourceDictionary.xaml"/>
That's it! You have successfully created a new dictionary and linked it to your project.
3.142.166.31