This is the 10th part of the NGTweet series. This is the first time I have written a 10 part series. It feels great. Hopefully there will be many more to come. In part 9, we saw the use of Data Triggers. In this part I am going to refactor the XAML code for couple of reasons.
First and foremost, there is lot of duplication. I have strong feeling about code quality and I don’t like code duplication. To manage the codebase better I would like to use the Styles and Templates feature available in Silverlight.
Secondly, there is a bug in inline data templates with Silverlight. It leads to memory leaks. The list controls used in the NGTweet application have been using the inline data templates all along. I want to be on the safer side.
Resources and Data Templates
To avoid the memory leak problem mentioned above, we make use of the data template feature available in Silverlight. We have already used this feature. But in this post I am going to demonstrate how we can extend it to make it reusable across elements like user controls and pages. This allows us to build consistent user interfaces. We can define data templates at multiple levels.
If a template is going to be used in only one user control or a single page, we can add it to the resources section of that particular user control or a page.
If a template is going to be used across the application, we can add it to the applications resources.
Usually templates definitions are lengthy and can be quite difficult to manage. For better manageability, we can split the template definitions into smaller chunks known as Resource Dictionaries. And then merge these dictionaries into the Application Resources. In this post I am going to use this method.
1. Create Resource Dictionary
The first step towards refactoring the inline data template is to create a new Resource Dictionary. This has an extension of XAML itself. Add a new item to the project and select item type as Silverlight Resource Dictionary
Note : Usually all the resources for a particular project like Styles, Images etc. are grouped under an Assets folder under the root directory. I have the path Assets/Styles for storing the resource dictionaries.
This file will have the root tag named ResourceDictionary.
2. Move Data Templates from user control to resource dictionary
The second step involves removing the inline data template from user control and moving it to the newly created resource dictionary. For simplicity I will not copy the code for data template here. You can refer to the attached source code to get the details. As we move the data template, its related dependencies like converters and reference namespaces also needs to be moved to the resource dictionary.
In order to identify the Data Template uniquely, we need to assign a identifier to it using the Key property. I have named the data template as TimeLineListDataTemplate.
3. Merge resources with the Application’s ResourceDictionary
As I mentioned earlier, we can have resources at different levels. We can merge resources at individual control level or at the application level as well. If a particular resource is likely to be used across the whole application its easier to add it in one central place which happens to be the Application Resource Dictionary. We use the following Xaml to achieve this :
<ResourceDictionary Source="Assets/Styles/TimeLineListItemStyle.xaml" />
<ViewModel:ViewModelLocator x:Key="Locator" />
This is added to the App.xaml file. Note that the ResorceDictionary needs to have the Key as well.
4. Refer Data Template from Resource Dictionary in the user control
The last step is to reference the Data Template in the user control or page. This is done using ItemTemplate dependency property of the list box. The syntax is similar to that of data binding, but we use the StaticResource markup extension.
If we run the application now, we see the same output as before.
Data Templates as well as styles are similar to CSS Stylesheets in HTML. They provide us a way of defining the visual styles in a central place. Using data template also improves performance of the application. The XAML parser is optimized for parsing data templates and rendering is faster. Externalizing data templates also helps us to indirectly address the memory leak issue with inline data templates. Although that cannot be a valid reason to use external data templates. Its sad that this issue has been around for quite sometime. Hopefully Microsoft will address it in near future.
As always I have uploaded the complete working solution to Dropbox.
Until next time Happy Programming
Note : The memory leak issue related to inline data templates is applicable only in Silverlight 4.