Oll*_*Oll 14 wpf prism resourcedictionary
鉴于我有一个shell应用程序和一些使用Microsoft CompoisteWPF(Prism v2)的独立模块项目......
在接收命令时,模块创建新的ViewModel并通过区域管理器将其添加到区域.
var viewModel = _container.Resolve<IMyViewModel>();
_regionManager.Regions[RegionNames.ShellMainRegion].Add(viewModel);
Run Code Online (Sandbox Code Playgroud)
我想我可以在模块中创建一个资源字典并设置一个数据模板来显示已加载的视图模型类型的视图(参见下面的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>
Run Code Online (Sandbox Code Playgroud)
编辑:
我可以通过添加到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>
Run Code Online (Sandbox Code Playgroud)
这很好,但这意味着在创建新模块时,需要添加App.xaml文件.我正在寻找的是模块的一种方式,因为它们加载动态添加到Application.Resources.这可能吗?
And*_*mes 21
为了避免你的shell应用程序必须知道你的模块和模块的任何信息,以任何方式进入shell,我会为你的模块提供如下界面:
IMergeDictionaryRegistry
{
void AddDictionaryResource(Uri packUri);
}
Run Code Online (Sandbox Code Playgroud)
您需要在模块代码中使用此接口:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您将在shell中实现此操作:
public MergeDictionaryRegistry : IMergeDictionaryRegistry
{
public void AddDictionaryResource(Uri packUri)
{
Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary()
{
Source = packUri;
});
}
}
Run Code Online (Sandbox Code Playgroud)
最后,在你的Bootstrapper的ConfigureContainer中:
public override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<IMergeDictionaryRegistry, MergeDictionaryRegistry>();
}
Run Code Online (Sandbox Code Playgroud)
这将为您提供所需的功能,您的Shell和您的模块将保持彼此独立.这样做的另一个好处是更易于测试,因为您无需启动Application测试模块代码(只需模拟IMergeDictionaryRegistry即可完成).
让我们知道这对你有何影响.
在每个模块的初始化中,您可以添加到应用程序资源:
Application.Current.Resources.MergedDictionaries
.Add(new ResourceDictionary
{
Source = new Uri(
@"pack://application:,,,/MyApplication.Modules.Module1.Module1Init;component/Resources.xaml")
});
Run Code Online (Sandbox Code Playgroud)
或者如果你按照每个模块的约定有一个名为"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"))
});
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8180 次 |
| 最近记录: |