What is the easiest way to share resources between UserControls in a WPF user management library?

It has a WPF user control library and two (or more) user controls. I need to use the same style in both user controls. How can I share this style? For example:

This is the style:

<Style x:Key="customLabelStyle" TargetType="Label"> ... </Style> 

User Management A:

 <UserControl x:Class="Edu.Wpf.Example.UserControlA" ...xmlns stuff... > <Grid> ... some xaml markup... <Label Style="{StaticResource customLabelStyle}"/> </Grid> </UserControl> 

UserControl B:

  <UserControl x:Class="Edu.Wpf.Example.UserControlB" ...xmlns stuff... > <Grid> ... some another xaml markup... <Label Style="{StaticResource customLabelStyle}"/> </Grid> </UserControl> 

So, how can I share this style between user controls in the library without involving the app.xaml application resource in it?

UPDATE

I can add Themes \ Generic.xaml to my library and define the style there. But in this case I have to use ComponentResourceKey as the style key. Correctly? This is a long and not very convenient expression ...

+8
wpf user-controls resourcedictionary
source share
3 answers

You can define shared resources in a separate ResourceDictionary , and then combine them into your UserControl resources using MergedDictionaries .

+2
source share

Say that you have one resource that defines colors, for example:

 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Color A="#FF" R="#FF" G="#22" B="#11" x:Key="MyRed"/> <Color A="#FF" R="#00" G="#FF" B="#21" x:Key="MyGreen"/> <Color A="#FF" R="#00" G="#22" B="#FF" x:Key="MyBlue" /> <SolidColorBrush x:Key="MyGreenBrush" Color="{StaticResource MyGreen}"/> <SolidColorBrush x:Key="MyRedBrush" Color="{StaticResource MyRed}"/> <SolidColorBrush x:Key="MyBlueBrush" Color="{StaticResource MyBlue}"/> </ResourceDictionary> 

And one more that defines some basic styles:

 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style TargetType="{x:Type TextBlock}" x:Key="PocTextBlock"> <Setter Property="FontSize" Value="16"/> </Style> <Style TargetType="{x:Type TextBox}" x:Key="MyTextBox"> <Setter Property="FontSize" Value="20"/> <Setter Property="Foreground" Value="{DynamicResource MyGreenBrush}"/> </Style> <Style TargetType="{x:Type TextBlock}" x:Key="MyResultTextBlock"> <Setter Property="FontSize" Value="16"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Foreground" Value="{DynamicResource MyGreenBrush}"/> </Style> <Style TargetType="{x:Type Border}" x:Key="MyBorder"> <Setter Property="BorderBrush" Value="{DynamicResource MyGreenBrush}"/> <Setter Property="BorderThickness" Value="4"/> <Setter Property="CornerRadius" Value="5"/> </Style> </ResourceDictionary> 

You can then add your resources to the App.xaml Application.Resources tag, as shown here:

 <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="OtherStyles.xaml"/> <ResourceDictionary Source="Colors.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application> 

Then in all of your UserControls you can use styles or brushes as StaticResources, as the sample code shows.

+12
source share

I found a solution that works during development (at least in VS2010):

 public static class Resource { private static readonly Dictionary<Uri, ResourceDictionary> SharedDictinaries = new Dictionary<Uri, ResourceDictionary>(); private static void onMergedDictionaryChanged(DependencyObject source, DependencyPropertyChangedEventArgs args) { FrameworkElement el = source as FrameworkElement; if (el == null) return; Uri resourceLocator = new Uri(GetMergedDictionary(source), UriKind.Relative); ResourceDictionary dictionary; if (SharedDictinaries.ContainsKey(resourceLocator)) dictionary = SharedDictinaries[resourceLocator]; else { dictionary = (ResourceDictionary)Application.LoadComponent(resourceLocator); SharedDictinaries.Add(resourceLocator, dictionary); } el.Resources.MergedDictionaries.Add(dictionary); } public static readonly DependencyProperty MergedDictionaryProperty = DependencyProperty.RegisterAttached("MergedDictionary", typeof (String), typeof (Resource), new FrameworkPropertyMetadata(null, onMergedDictionaryChanged)); [AttachedPropertyBrowsableForType(typeof(FrameworkElement))] public static String GetMergedDictionary(DependencyObject source) { return (String) source.GetValue(MergedDictionaryProperty); } public static void SetMergedDictionary(DependencyObject source, String value) { source.SetValue(MergedDictionaryProperty, value); } } 

This attached property can be applied to a FrameworkElement. Imagine customLabelStyle is defined in the Styles.xaml dictionary in the Edu.Wpf.Example project. Thus, this style can be applied as follows:

 <UserControl x:Class="Edu.Wpf.Example.UserControlA" ... xmlns:res="clr-namespace:Edu.Wpf.Example.Resources" res:Resource.MergedDictionary="/Edu.Wpf.Example;component/Resources/Styles.xaml"> ... <Label Style="{StaticResource customLabelStyle}"/> </UserControl> 
+1
source share

All Articles