WPF MEF +棱镜初始区域加载 [英] WPF MEF + Prism initial Region loading

查看:140
本文介绍了WPF MEF +棱镜初始区域加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在WPF中使用MEF和Prism在三个不同的区域编写了MVVM应用程序.代码跨越两个模块,可以在App.Config中找到.

I have written an MVVM app in WPF using MEF and Prism with three different regions. Code is across two modules, being discovered in the App.Config.

我所有的导航命令和结构都工作得很好,但是我困惑的一件事是如何在应用启动时设置加载到每个区域的初始Views,因为我似乎无处可做.此外,如果我在MainViewModel构造函数的末尾添加一些内容以显式导航到屏幕集A,则似乎有其他内容将其覆盖并加载了其他一组视图.

I have all the navigation commands and structure working perfectly fine, but the one thing I am confused on is how to set the initial Views loaded into each region at app startup as there seems to be nowhere I can do this. Furthermore if I add something to the end of the MainViewModel constructor to explicitly navigate to screen set A, something else seems to be overriding it and loading a different set of views to start with.

这似乎也取决于我在app.config中加载模块的顺序,这似乎是不可取的.如果我最后加载管理模块,则从管理模块加载一组屏幕,如果我最后加载搜索模块,则从搜索模块加载一组视图,在这种情况下,它甚至找不到要显示的视图.主要地区.

It also seems dependent on what order I load the modules in on the app.config which seems undesirable. If I load the Admin module last, it loads a set of screens from the admin module, if I load the search module last, it loads a set of views from the search module and in this case, it is not even finding a View for the main region.

使用MEF和配置发现时,在应用启动时指定将哪些视图加载到每个区域的方法是什么?

What is the method for specifying what Views are loaded into each region at app startup when using MEF and config discovery?

using System;
using System.ComponentModel.Composition;
using Microsoft.Practices.Prism.Regions;

namespace CRM.GUI.WPF.Shared.Infrastructure.Behaviour
{
    [Export(typeof(AutoPopulateExportedViewsBehavior))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class AutoPopulateExportedViewsBehavior : RegionBehavior, IPartImportsSatisfiedNotification
    {
        protected override void OnAttach()
        {
            AddRegisteredViews();
        }

        public void OnImportsSatisfied()
        {
            AddRegisteredViews();
        }

        private void AddRegisteredViews()
        {
            if (Region != null)
            {
                foreach (var viewEntry in RegisteredViews)
                {
                    if (viewEntry.Metadata.RegionName == Region.Name)
                    {
                        var view = viewEntry.Value;

                        if (!Region.Views.Contains(view))
                        {
                            Region.Add(view);
                        }
                    }
                }
            }
        }

        [ImportMany(AllowRecomposition = true)]
        public Lazy<object, IViewRegionRegistration>[] RegisteredViews { get; set; }
    }
}

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    [MetadataAttribute]
    public class ViewExportAttribute : ExportAttribute, IViewRegionRegistration
    {
        public ViewExportAttribute()
            : base(typeof(object))
        { }

        public ViewExportAttribute(string viewName)
            : base(viewName, typeof(object))
        { }

        public string RegionName { get; set; }
    }

已使用

[ViewExport(RegionName = RegionNames.MainRegion)]
public partial class ReportView

推荐答案

根据我的理解, Prism 会加载并默认显示在每个视图上注册的第一个 View 区域(如果在 ContentControl 项目上设置了区域,则只会显示第一个视图).

Based on my understanding, Prism loads and show by default the first View that gets registered on each Region (Only the first View would be shown if the region is set on a ContentControl item).

因此,您可以停用不想在启动时显示的每个 RegionBehavior 上不需要的视图.这样一来,当添加所需的 StartUp View 时,由于没有其他 active ,它会被激活. 查看.

Therefore, you could deactivate the undesired Views on each RegionBehavior you don't want to show at startUp. This would make that when the desired StartUp View is added, it would get activated as there is no other active View yet.

另一种替代方法是在相应的 Module initialize()方法上注册每个 View ,而不是使用 RegionBehaviours 强>.因此,最后,在将每个视图添加到相应的区域之后,您将决定停用 视图 启动视图 .

Another alternative would be to register each View on the corresponding Module initialize() method, instead of using RegionBehaviours. So finally, after adding each View to the corresponding Region, you would decide to deactivate the View whether it is the StartUp View or not.

更新:

以下实现显示了每个 RegionBehavior 停用 非启动视图的可能选择.为了获得更好的解决方案,您可以创建一个字典或一个简单的静态类,以返回相应的 Region StartUpView 名称,然后如图所示对其进行调用下方:

The following implementation shows a possible alternative for deactivating non-startup Views on each RegionBehavior. In order to get a more elegant solution, you could create a dictionary or a simple static class that would return the StartUpView name for the corresponding Region, and then call it as shown below:

private void AddRegisteredViews()
{
   ...
       var view = viewEntry.Value;

       if (!Region.Views.Contains(view))
       {
            Region.Add(view);
            if (view.GetType().Name != StartUpViewNames.getViewNameFromRegion(Region))
            {
                 Region.deactivate(view);
            }
       }
  ...
}

请注意,在找到 StartUpView 后,我将其保持为 active 状态,它会继续停用以下添加的视图,但是您可以离开它们 active .正如我提到的,将显示的视图将是在 Region (区域)中第一个启用 Active 的视图.

Notice that I after the StartUpView is found and it is kept active, it continues deactivating the following added views, but you could leave them active. As I mentioned, the View that would be shown, would be the first one which gets Active in the Region.

我希望这会有所帮助, 问候.

I hope this helps, Regards.

这篇关于WPF MEF +棱镜初始区域加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆