【问题标题】:Prism, MVVM and modularity棱镜、MVVM 和模块化
【发布时间】:2012-01-04 13:31:55
【问题描述】:

我(非常)最近开始研究 Prism(针对 WPF 应用程序),并且一直在为我的团队开发一个小型演示应用程序。我的问题是一个相当笼统的问题,但我找不到一个简单的例子来指导我:
假设我有 Shell(在主模块中),并且 Shell 有一个区域应该由来自不同模块的内容填充(顺便说一句,这是个好主意吗?)。
这究竟是如何发生的?谁负责将来自其他模块的视图添加到 Shell 的指定区域?何时初始化其他模块的相关视图模型?代码示例/指向它们的链接将不胜感激。

谢谢!

编辑:问题拆分,请参阅the new question

【问题讨论】:

  • 请拆分您的问题。添加的部分应该进入他们自己的问题。否则这里会变得很丑。

标签: wpf mvvm prism modularity


【解决方案1】:

在您的引导程序中,您将定义一个模块目录(覆盖 CreateModuleCatalog),其中列出了将在您的应用程序中使用的模块。每个模块都有一个实现 IModule 的类,其中包含一个 Initialize 方法,该方法在创建模块时被调用。在此您将定义要添加到外壳区域的内容:

    public void Initialize()
    {
        RegisterViewsAndServices(); //Method to register dependencies
        IMyViewModel model = _container.Resolve<IMyViewModel>();
        _regionManager.Regions[RegionNames.ShellHeaderRegion].Add(model);
    }

在这里,我向 shell 添加了一个视图模型,并在外部定义了一个资源字典,用于确定应通过 DataTemplate 将哪个视图应用于它。

Prism 文档(尤其是第 2 章)提供了很多关于这方面的有用信息。 http://msdn.microsoft.com/en-us/library/gg406140.aspx

【讨论】:

    【解决方案2】:

    是的,分离 shell 和视图是个好主意。

    RegionManager 负责将视图添加到区域中。因此,您将区域注册到 RegionManager 以及将视图注册到 RegionManager。

    在 shell 中,你最终会得到类似的东西:

    <Window xmlns:Regions="clr-namespace:Microsoft.Practices.Prism.Regions;assembly=Microsoft.Practices.Prism"
            xmlns:Inf="clr-namespace:YourNamespace.Infrastructure;assembly=YourNamespaceInfrastructure">
        <Grid>
            <ContentControl 
                Regions:RegionManager.RegionName="{x:Static Inf:RegionNames.MainRegion}"/>
        </Grid>
    </Window>
    

    现在您必须将视图注册到它将驻留的区域:

    public class FirstModule : IModule
    {
        public void Initialize( )
        {
            RegionManager.RegisterViewWithRegion( RegionNames.MainRegion,
                typeof( MainView ) );
            RegionManager.RegisterViewWithRegion( RegionNames.SecondRegion,
                ( ) => Container.Resolve<ISomethingViewModel>( ).View );
        }
    }
    

    示例代码显示了这两种类型的注册。第一个是视图优先的方法,后者是视图模型优先的方法。

    [编辑]

    区域名称在基础设施模块的静态类中定义:

    namespace YourNamespace.Infrastructure
    {
        public static class RegionNames
        {
            public const string MainRegion = "MainRegion";
            //...
        }
    }
    

    [/EDIT]

    【讨论】:

    • 谢谢!您的意思是在基础设施项目中定义区域的名称吗?这确实比让我的模块神奇地知道其区域名称更有意义,但我不确定你是如何做到的。
    • @Noich 是的,区域名称驻留在我的基础设施程序集中的静态类中。看看更新的答案。
    • 再次感谢。有关更多问题和说明,请参阅我原始帖子的 2 处编辑。感谢您的帮助。
    猜你喜欢
    • 2012-01-05
    • 2011-02-15
    • 2017-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    相关资源
    最近更新 更多