One of the very useful constructs that is found in Wpf but not in Silverlight is the DynamicResource. In Wpf, when you want a resource such as a brush to be dynamically updatable at runtime, you use DynamicResource where otherwise you would use StaticResource. We have created a way to simulate the functionality of Wpf’s DynamicResource in DotNetBar for Silverlight.
Creating Dynamic Resources
To create a dynamic resource, the first step is to define a class which inherits from DevComponents.Silverlight.Controls.DynamicResourceDictionary. Then, for each resource you wish to include, define a property with a public getter. The property’s Name is the Key value by which the resource is referenced and the property’s Type is the type of the resource. It doesn’t matter how or where the actual resources are defined, only that the property getter returns the desired resource. However, DynamicResourceDictionary is a wrapper for System.Windows.ResourceDictionary and makes it easy to use an actual resource dictionary as the backing store for your resources.
The dynamic resource dictionary, once created, must be inserted into the resources collection of one of the elements of the Visual Tree where it can be found relative to the element on which the resource is being set, up to and including the application’s resources. Elements are searched beginning with the element on which the property is set and moving up the tree. The first DynamicResourceDictionary that is found that has a matching property is used.
Using Dynamic Resources
All color theme resources and many other resources utilized by DotNetBar libraries are implemented as dynamic resources. Using any of these resources in your own controls is simply a matter of setting one of the attached properties that are defined in the static class DevComponents.Silverlight.Controls.DynamicResource. The following attached dependency properties are defined in DynamicResource:
- ForegroundKey – for setting the Foreground of the FrameworkElement on which the attached DP is set.
- BackgroundKey – for setting the Background of the FrameworkElement on which the attached DP is set.
- BorderBrushKey – for setting the BorderBrush of the FrameworkElement on which the attached DP is set.
- StrokeKey – for setting the Stroke of the FrameworkElement on which the attached DP is set.
- FillKey – for setting the Fill of the FrameworkElement on which the attached DP is set.
Each of these attached DPs acts as a parameter to a behavior the function of which is to set the appropriate property value on the element. The value of the attached DP is the resource key which is to be applied. The element on which the attached DP value is being set is the element which receives the actual resource once resolved. For example, to set the BorderBrush property of a Border to the resource with the key "CalendarViewBorder" and its Background to a resource with the key "CalendarViewBackgroundFill", you would use the following Xaml:
(controls = namespace DevComponents.Silverlight.Controls)
<Border controls:DynamicResource.BackgroundKey="CalendarViewBackgroundFill" controls:DynamicResource.BorderBrushKey="CalendarViewBorder" />
The same thing in code looks like this:
Border border = new Border(); DynamicResource.SetBorderBrushKey(border, "CalendarViewBorder"); DynamicResource.SetBackgroundKey(border, "CalendarViewBackgroundFill");
If an attempt is made to set a resource to a property on an element and the element does not define the property, an exception is thrown. The following, for example, will result in an exception:
Instead, use this: