如何使用 MEF 从另一个程序集中加载 WPF 树视图资源?

How to load WPF treeview resources from another assembly using MEF?

我正在创建一个使用 MEF 加载其插件的 WPF 应用程序。 如何包含我正在使用 MEF 加载的另一个程序集中的资源? 具体来说,我想在外部程序集中创建一个 HierarchicalDataTemplate,并在启动时组合应用程序时将其动态加载到 Treeview.Resources。 这样的事情可能吗?

我正在使用 Caliburn.Micro 如果它很重要,但我确信这个问题适用于一般的 WPF 应用程序。

如果您尝试加载静态资源,您应该在加载主资源之前加载资源 window。 如果您尝试加载动态资源,您应该在加载使用该资源的视图之前加载该资源。

您应该以任何方式添加对资源的引用,方法是在引导时将其添加到 Wpf 应用程序合并字典。

//On the bootstrapper add the following code
 ResourceDictionary rd = new ResourceDictionary
                                {
                                    Source =
                                        new Uri(
                                            "pack://application:,,,/DllName;component/Themes/ResourceName.xaml",
                                            UriKind.RelativeOrAbsolute)
                                };


Application.Current.Resources.MergedDictionaries.Add(rd);

最后我就是这样做的。
因为如果您使用 MEF 的 DirectoryCatalog 加载程序集,Caliburn.Micro 将无法正常工作,所以我必须手动执行。波纹管是代码的简化部分,它执行它并加载包含在单独的 resources.xaml 文件中的 ResourceDictionary。

FileInfo[] filesInfo = new DirectoryInfo(pluginPath).GetFiles("*.dll");
AssemblySource.Instance.AddRange(filesInfo.Select(fileInfo => Assembly.LoadFrom(fileInfo.FullName)));

// load resources from plugins
var dictionaries = App.Current.Resources.MergedDictionaries;
dictionaries.Clear();

foreach (FileInfo fileInfo in filesInfo)
{
    string assemblyName = Path.GetFileNameWithoutExtension(fileInfo.Name);
    string uriString = assemblyName + @";component/resources.xaml";

    try
    {
        dictionaries.Add(new ResourceDictionary { Source = new Uri(uriString, UriKind.Relative) });
    }
    catch
    {
        // do some logging
    }