我已经在WPF中使用MEF和Prism在三个不同的区域编写了MVVM应用程序。代码位于App.Config中发现的两个模块之间。
我的所有导航命令和结构都工作正常,但是我感到困惑的是,如何设置在应用启动时将初始视图加载到每个区域中,因为我似乎无处可做。此外,如果我在MainViewModel构造函数的末尾添加一些内容以显式导航到屏幕集A,则似乎有其他内容将其覆盖并加载了另一组视图。
这似乎也取决于我在app.config中加载模块的顺序,这似乎是不可取的。如果我最后加载管理模块,则从管理模块加载一组屏幕,如果我最后加载搜索模块,则从搜索模块加载一组视图,在这种情况下,甚至没有找到用于主要地区。
使用MEF和配置发现时,用于指定在应用启动时在每个区域中加载哪些视图的方法是什么?
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
根据我的理解,棱镜负载和默认显示第一视图是被每个注册的地区(只有第一个视图,如果该区域被设置在将显示在ContentControl中项目)。
因此,您可以在不想在启动时显示的每个RegionBehavior上停用不需要的视图。这样一来,当添加了所需的“启动视图”时,它将被激活,因为还没有其他活动视图。
另一种选择是在相应的Module initialize()方法上注册每个View,而不是使用RegionBehaviours。因此,最后,在将每个视图添加到相应的Region之后,您将决定停用该视图,无论它是否为“启动视图”。
更新:
以下实现显示了在每个RegionBehavior上停用非启动视图的可能选择。为了获得更好的解决方案,您可以创建一个字典或一个简单的静态类,以返回相应Region的StartUpView名称,然后按如下所示进行调用:
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并将其保持活动状态后,我将继续停用以下添加的视图,但是您可以将其保持活动状态。正如我提到的,将显示的视图将是第一个在Region中变为活动的视图。
希望这对您有所帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句