复合WPF(Prism)模块资源数据模板

复合WPF(Prism)模块资源数据模板,wpf,prism,resourcedictionary,Wpf,Prism,Resourcedictionary,假设我有一个shell应用程序和两个使用Microsoft CompositeWPF(Prism v2)的独立模块项目 收到命令后,模块将创建新的ViewModel,并通过区域管理器将其添加到区域中 var viewModel = _container.Resolve<IMyViewModel>(); _regionManager.Regions[RegionNames.ShellMainRegion].Add(viewModel); var viewModel=\u contai

假设我有一个shell应用程序和两个使用Microsoft CompositeWPF(Prism v2)的独立模块项目

收到命令后,模块将创建新的ViewModel,并通过区域管理器将其添加到区域中

var viewModel = _container.Resolve<IMyViewModel>();
_regionManager.Regions[RegionNames.ShellMainRegion].Add(viewModel);
var viewModel=\u container.Resolve();
_regionManager.Regions[RegionNames.ShellMainRegion].Add(viewModel);
我认为我可以在模块中创建一个资源字典,并设置一个数据模板来显示加载的视图模型类型的视图(请参见下面的xaml)。但是当视图模型被添加到视图中时,我得到的只是打印出来的视图模型名称空间

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:Modules.Module1.ViewModels"
    xmlns:vw="clr-namespace:Modules.Module1.Views"
>
    <DataTemplate DataType="{x:Type vm:MyViewModel}">
        <vw:MyView />
    </DataTemplate>
</ResourceDictionary>

编辑:

我可以通过添加到App.xaml来让它工作

<Application.Resources>
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/Module1;component/Module1Resources.xaml"/>
        <ResourceDictionary Source="pack://application:,,,/Module2;component/Module2Resources.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</Application.Resources>


这很好,但这意味着在创建新模块时,需要将App.xaml文件添加到。我要寻找的是模块的一种方式,当它们加载到Application.Resources时,动态地添加到Application.Resources。这可能吗?

为了避免您的shell应用程序必须了解您的模块以及您的模块以任何方式进入shell,我将为您的模块提供如下接口:

IMergeDictionaryRegistry
{
     void AddDictionaryResource(Uri packUri);
}
您可以在模块代码中请求此接口:

public class MyModule : IModule
{
     IMergeDictionaryRegistry _merger;
     public MyModule(IMergeDictionaryRegistry merger)
     {
          _merger = merger;
     }

     public void Initialize()
     {
          _merger.AddDictionaryResource(new Uri("pack://application:,,,/Module1;component/Module1Resources.xaml");
     }
}
然后,您将在shell中实现此功能:

public MergeDictionaryRegistry : IMergeDictionaryRegistry
{
     public void AddDictionaryResource(Uri packUri)
     {
          Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
          {
               Source = packUri;
          });
     }
}
最后,在引导程序的ConfigureContainer中:

public override void ConfigureContainer()
{
     base.ConfigureContainer();
     Container.RegisterType<IMergeDictionaryRegistry, MergeDictionaryRegistry>();
}
public override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType();
}
这将为您提供所需的功能,并且您的Shell和模块将保持相互独立。这还有一个额外的好处,即更易于测试,因为您无需启动
应用程序来测试模块代码(只需模拟
IMergeDictionaryRegistry
,您就完成了)


让我们了解您的情况。

在每个模块的初始化过程中,您可以添加到应用程序资源中:

Application.Current.Resources.MergedDictionaries
                .Add(new ResourceDictionary
                {
                    Source = new Uri(
                        @"pack://application:,,,/MyApplication.Modules.Module1.Module1Init;component/Resources.xaml")
                });
或者,如果您遵循每个模块的约定,则每个模块都有一个名为“Resources.xmal”的资源字典


这似乎是一个很大的工作

就我个人而言,我只是在视图的
UserControl.Resources
部分声明了一个资源字典,如下所示

<UserControl.Resources>
    <ResourceDictionary Source="../Resources/MergedResources.xaml" />
</UserControl.Resources>

然后,该合并词典指向我需要包含的任何资源

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Iconography.xaml" />
    <ResourceDictionary Source="Typeography.xaml" />
</ResourceDictionary.MergedDictionaries>

我想你应该在那里声明你的数据模板


嗯。

谢谢。WPF知道如何使用DataTemplate呈现ViewModel(请参阅)。问题是让应用程序了解另一个程序集中的DataTemplate。我编辑了这篇文章以提供更多细节。哦,我知道你在做什么。您可能需要为模块提供一些接口(IMergeDictionaryRegistration w/a接受包URL的方法),并将它们附加到应用程序的资源字典中。只是一个理论,还有。。。我很好奇你的情况如何。让我们知道。这是一个有趣的方法。答案的第一部分要求模块深入应用程序。我建议不要这样做,因为这是不稳定的。第二种方法更合适。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Iconography.xaml" />
    <ResourceDictionary Source="Typeography.xaml" />
</ResourceDictionary.MergedDictionaries>