鉴于我有一个shell应用程序和几个使用Microsoft CompoisteWPF(Prism v2)的独立模块项目......
接收命令后,模块会创建一个新的ViewModel,并通过区域管理器将其添加到某个区域。
var viewModel = _container.Resolve<IMyViewModel>();
_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。这可能吗?
答案 0 :(得分:21)
为了避免您的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;
});
}
}
最后,在你的Bootstrapper的ConfigureContainer中:
public override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<IMergeDictionaryRegistry, MergeDictionaryRegistry>();
}
这将为您提供所需的功能和您的Shell,您的模块将保持彼此独立。这样做的另一个好处是更易于测试,因为您无需启动Application
来测试模块代码(只需模拟IMergeDictionaryRegistry
即可完成)。
告诉我们这是怎么回事。
答案 1 :(得分:6)
在每个模块的初始化过程中,您可以添加到应用程序资源:
Application.Current.Resources.MergedDictionaries
.Add(new ResourceDictionary
{
Source = new Uri(
@"pack://application:,,,/MyApplication.Modules.Module1.Module1Init;component/Resources.xaml")
});
或者,如果您遵循每个模块的约定,则会有一个名为“Resources.xmal”的资源字典......
protected override IModuleCatalog GetModuleCatalog()
{
var catalog = new ModuleCatalog();
AddModules(catalog,
typeof (Module1),
typeof(Module2),
typeof(Module3),
typeof(Module4));
return catalog;
}
private static void AddModules(ModuleCatalog moduleCatalog,
params Type[] types)
{
types.ToList()
.ForEach(x =>
{
moduleCatalog.AddModule(x);
Application.Current.Resources.MergedDictionaries
.Add(new ResourceDictionary
{
Source = new Uri(string.Format(
@"pack://application:,,,/{0};component/{1}",
x.Assembly,
"Resources.xaml"))
});
});
}
答案 2 :(得分:2)
这一切看起来都很重要!
就个人而言,我只是在我的视图的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>
我猜你在那里宣布你的数据模板。
HTH。