Adding a static ResourceDictionary to UserControls before the XAML is parsed
I have one WPF control that I want to use in my WinForms application (using an ElementHost) in several places (=> multiple instances of this control).
Furthermore I want all instances of my UserControl to share one single Instance of a ResourceDictionary.
In WPF applications I would achieve that by merging my ResourceDictionary in the Application Resources.
However, I don't want to create an WPF Application Instance in my WinForms application. Instead I am looking for another way.
I found one solution but I am hoping you know a better way that does not require any code behind:
public static class StaticRDProvider
{
static ResourceDictionary rd;
static StaticRDProvider()
{
var uri = new Uri("WpfControls;Component/GlobalResourceDictionary.xaml", UriKind.Relative);
rd = (ResourceDictionary) Application.LoadComponent(uri);
}
public static ResourceDictionary 开发者_如何学运维GetDictionary
{
get { return rd; }
}
}
UserControl.xaml.cs:
public partial class MyCustomUserControl : UserControl
{
public MyCustomUserControl()
{
Resources.MergedDictionaries.Add(StaticRDProvider.GetDictionary);
InitializeComponent();
}
}
That works. But I prefer a solution that only works with XAML. Plus I want to be able to use StaticResources. Therefore adding the static ResourceDictionary to the Controls MergedDictionaries after the control was initialized is not an option.
I tried the following, but it throws a strange "stack is empty" exception:
<UserControl x:Class="WpfControls.MyCustomUserControl"
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:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:WpfControls="clr-namespace:WpfControls" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<x:Static Member="WpfControls:StaticRDProvider.GetDictionary"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
</Grid>
Maybe someone knows a better approach.
Thanks, TwinHabit
Did you try loading the RD inside your UserControl the same you would do it with the Application class?
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WpfControls;Component/GlobalResourceDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
This way you just specify the URI in your user control, and avoid the static members hassle altogether.
BTW, make sure to use the correct URI syntax if the RD is not in the same assembly as the UserControl. For example: pack://application:,,,/YourAssembly;component/Subfolder/YourResourceFile.xaml (more info on pack URIs)
精彩评论