2009-07-23 42 views
13

假设我有一个外壳程序和几个使用Microsoft CompoisteWPF(棱镜v2)的单独的模块项目...复合WPF(棱镜)模块资源数据模板

在接收命令,模块创建一个新的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> 

这很好的工作,但它意味着创建新的模块,应用程序。需要将xaml文件添加到。我正在寻找的是模块的一种方式,因为它们会加载到动态添加到Application.Resources中。这可能吗?

回答

5

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

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")) 
           }); 
       }); 
} 
19

为了避免不必了解你的模块,并从伸手到以任何方式外壳的模块任何你的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"); 
    } 
} 

你会然后在壳里做这个实现这一点:

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>(); 
} 

这会得到你想要壳牌和你的模块将保持相互独立的功能。这有更多的可测试性,因为你不需要旋转Application来测试你的模块代码(只需模拟IMergeDictionaryRegistry,你就完成了)。

让我们知道这是怎么回事。

+0

谢谢。 WPF知道如何使用DataTemplate呈现ViewModel(请参阅:http://msdn.microsoft.com/zh-cn/magazine/dd419663.aspx#id0090097)。问题是让应用程序了解另一个程序集中的DataTemplate。我编辑了这篇文章以提供更多细节。 – Oll 2009-07-23 19:27:00

+0

哦,我明白你在做什么。您可能必须为模块提供一些接口(IMergeDictionaryRegistration,接受包url的方法),并将它们附加到应用程序的资源字典中。只是一个理论。 – 2009-07-23 22:32:19

1

这一切都好像很多工作!

就个人而言,我只需要声明一个资源字典在我看来是这样的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。