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

标签 wpf prism resourcedictionary

鉴于我有一个 shell 应用程序和几个使用 Microsoft CompoisteWPF (Prism v2) 的独立模块项目...

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

var viewModel = _container.Resolve<IMyViewModel>();
_regionManager.Regions[RegionNames.ShellMainRegion].Add(viewModel);

我认为我可以在模块内创建一个资源字典,并设置一个数据模板来显示已加载的 View 模型类型的 View (请参见下面的 xaml)。但是当 View 模型添加到 View 中时,我得到的只是打印出来的 View 模型命名空间。

<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 中。这可能吗?

最佳答案

为了避免您的 shell 应用程序必须了解有关您的模块的任何信息以及您的模块以任何方式接触到 shell,我将为您的模块提供一个如下所示的接口(interface):

IMergeDictionaryRegistry
{
     void AddDictionaryResource(Uri packUri);
}

您会在模块代码中请求此接口(interface):

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 的配置容器中:

public override void ConfigureContainer()
{
     base.ConfigureContainer();
     Container.RegisterType<IMergeDictionaryRegistry, MergeDictionaryRegistry>();
}

这将为您提供所需的功能,并且您的 Shell 和模块将保持彼此独立。这样做的另一个好处是更具可测试性,因为您无需启动 Application 来测试您的模块代码(只需模拟 IMergeDictionaryRegistry 即可完成)。

请告诉我们您的情况如何。

关于wpf - 复合WPF(Prism)模块资源数据模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1172171/

相关文章:

c# - XAML 中的触发器属性

wpf - WPF与PRISM 4.0和Unity的工作示例

c# - WPF 资源字典组织

wpf - HighlightBrushKey 设置在 Windows 7 中不起作用

wpf - 是否可以将 QT 应用程序托管到 WPF 应用程序中?

WPF - 来自 base 64 字符串(或字节数组)的窗口图标的 ImageSource

wpf - 如何绑定(bind)到 WPF ColorAnimation 中的颜色?

c# - 如何从 Prism 应用程序的各个模块中的 Unity 容器中获取相同的对象实例?

wpf - 指定的元素已经是另一个元素的逻辑子元素

wpf - 如何覆盖全局样式(没有 x :Key), 或将命名样式应用于所有类型目标控件?