In Previous post - Use an attached Property to set Resources/Styles , we discussed how to leverage the Attached property to easily set the resources/styles for a user control.
Follow the discussion on Custom WPF Binding Markup Extension, there is an alternative approach that makes use of the BindingExtension.
The following discussion uses the BindingDecoratorBase, a class that is contributed in the post of Custom WPF Binding Markup Extension.
The code that imple the BindingExtension is as follow.
namespace Com.Boqwang.Utils { // below is modeled after the code described here // http://www.hardcodet.net/2008/04/wpf-custom-binding-class /// <summary> /// MyCustomBinding example/ /// </summary> public class CustomResourceExtension : BindingDecoratorBase { /// <summary> /// the resource in PackUri format /// </summary> public string ResourcePackUri { get; set; } public override object ProvideValue(IServiceProvider provider) { object val = base.ProvideValue(provider); DependencyObject targetObject; DependencyProperty targetProperty; bool status = TryGetTargetItems(provider, out targetObject, out targetProperty); if (status) { // in this branch, the targetObject as well as the targetProperty should both be Non-null if (targetProperty.Name != "Style") { throw new InvalidOperationException("TargetProperty 'Resources' required!"); } var control = targetObject as UserControl; if (control == null) { //throw new NotSupportedException(" throw new InvalidOperationException("TargetObject 'UserControl' required!"); } if (string.IsNullOrEmpty(ResourcePackUri)) { throw new InvalidOperationException("'ResourcePackUri' cannot be Null or Empty"); } Uri uri = new Uri(ResourcePackUri); ResourceDictionary resource = new ResourceDictionary(); resource.Source = uri; if (control.Resources.MergedDictionaries.FirstOrDefault(r => r.Source == uri) == null) { control.Resources.MergedDictionaries.Add(resource); } } else { throw new InvalidOperationException("Undefined DependencyObject or DependencyProperty"); } return val; } } }
To make this work, I overloads the use of Style DepedencyProperty. Let's see how to use the MarkupExtension.
<UserControl x:Class="MorganStanley.FutOpt.TRecsSupportModule.View.DashboardView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Com.Boqwang." > <UserControl.Style> <local:CustomResourceExtension ResourcePackUri="pack://application:,,,/MyModule;component/Resource/Style/MergedStyles.xaml" /> </UserControl.Style>
and as the previous post, the MergedStyles.xaml file looks liks this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="pack://application:,,,/TRecsSupportModule;component/Resource/Style/DarkStyles.xaml"/> <ResourceDictionary Source="pack://application:,,,/TRecsSupportModule;component/Resource/Style/Styles.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary>
The code here are suject to future changes.