Adding a static ResourceDictionary to UserControls before the XAML is parsed

妖精的绣舞 提交于 2019-12-07 06:59:42

问题


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


回答1:


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)



来源:https://stackoverflow.com/questions/3799515/adding-a-static-resourcedictionary-to-usercontrols-before-the-xaml-is-parsed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!