Modular Silverlight Development, App.xaml, Blend and Resources

As I was working on one of my personal learning projects, I encountered a small problem. The project was Prism based with multiple modules.  I wanted to isolate my resource files, so I created a separate project that included my XAML resources, such as styles.  This approach works just fine by using merged dictionaries in App.xaml:

<Application 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   x:Class="MyApp.Silverlight.App"
            >
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/MyResources.Silverlight.Common;component/Resources/MyResourcesDictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

 

Now I can reference those resource in my other modules’ screens and use them.  Now back to the original issue.  I can use styles from MyResourceDictionary.xaml, but Blend generates an error for me – it cannot find my resources.  Here is an easy way to overcome this issue.  You have to add the same dictionary into the resources of each screen:  In the example below I am showing resources area for a user control called MySampleView from MyApp module.,

    <MyApp:MySampleView.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/MyResources.Silverlight.Common;component/Resources/MyResourcesDictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <resource:Resource x:Key="LocalizedResource"/>
        </ResourceDictionary>
    </MyApp:MySampleView.Resources>

As you can see, I combine the styles dictionary with a local resource, in example localized user strings.  You can just as easily add converters, etc… in the same fashion.

There is some cost of course associated with merging dictionaries into each screen, but using Blend is a big benefit.  You can get around this issue by keeping this code commented out, and uncomment when using Blend

There is also another solution, involving having #DEBUG that moves this exact code into code behind of each view.  Of course, this is annoying as well, and this is when the base class for the view comes in.  Here is the code I could add to it to accomplish the same as XAML approach:

#if DEBUG
            var dictionary = new ResourceDictionary() 
                { Source = new Uri("/MyResources.Silverlight.Common;component/Resources/MyResourceDictionary.xaml", UriKind.RelativeOrAbsolute) };
            Resources.MergedDictionaries.Add(dictionary);
#endif

 

This of course underscores the usefulness of having base classes for all your major components, such as views in your applications.  It could be an inconvenience since you cannot just add new user control.  You would have to edit both XAML and code behind to change the inheritance structure of your user controls (views).

<MyApp:MySampleViewBase
   x:Class="MyApp.Views.MySampleView"

public partial class MySampleView : MySampleViewBase, IMySampleView

 

You can further optimize this process by creating custom control templates that would write all this code for you.  This way you would not have to modify the files after creating a new user control.

Thanks.

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *