1、新建Infrastructure项目
A、新建IViewRegionRegistration类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Infrastructure
{
public interface IViewRegionRegistration
{
string RegionName { get; }
}
}
B、新建ViewExportAttribute类
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Infrastructure
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
[MetadataAttribute]
public sealed class ViewExportAttribute : ExportAttribute, IViewRegionRegistration
{
public ViewExportAttribute()
: base(typeof(object))
{ }
public ViewExportAttribute(string viewName)
: base(viewName, typeof(object))
{ }
public string ViewName { get { return base.ContractName; } }
public string RegionName { get; set; }
}
}
C、新建AutoPopulateExportedViewsBehavior类,继承 RegionBehavior, IPartImportsSatisfiedNotification
using Microsoft.Practices.Prism.Regions;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Infrastructure
{
//RegionBehavior需引入Microsoft.Practices.Prism.Composition.dll
[Export(typeof(AutoPopulateExportedViewsBehavior))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class AutoPopulateExportedViewsBehavior : RegionBehavior, IPartImportsSatisfiedNotification
{
protected override void OnAttach()
{
AddRegisteredViews();
}
public void OnImportsSatisfied()
{
AddRegisteredViews();
}
private void AddRegisteredViews()
{
if (this.Region != null)
{
foreach (var viewEntry in this.RegisteredViews)
{
if (viewEntry.Metadata.RegionName == this.Region.Name)
{
var view = viewEntry.Value;
if (!this.Region.Views.Contains(view))
{
this.Region.Add(view);
}
}
}
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "MEF injected values"), ImportMany(AllowRecomposition = true)]
public Lazy<object, IViewRegionRegistration>[] RegisteredViews { get; set; }
}
}
2、在调用项目使用[ViewExport(RegionName = "RegionLoginTopMain")]属性
using Infrastructure;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace FrameOne.Views
{
/// <summary>
/// FrameOneView.xaml 的交互逻辑
/// </summary>
//[Export(typeof(FrameOneView))]
//[Export("FrameOneView", typeof(FrameOneView))]
[ViewExport(RegionName = "RegionLoginTopMain")]
// [PartCreationPolicy(CreationPolicy.NonShared)]
public partial class FrameOneView : UserControl
{
public FrameOneView()
{
InitializeComponent();
}
}
}
3、添加一个空的类
using FrameOne.Views;
using Microsoft.Practices.Prism.MefExtensions.Modularity;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.ServiceLocation;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//IModule需引入Microsoft.Practices.Prism.Composition.dll
//ModuleExport需引入Microsoft.Practices.Prism.MefExtensions.dll
//ModuleExport需引入System.ComponentModel.Composition.dll
namespace FrameOne
{
public class FrameOneInit
{
}
}
4、Bootstrapper中将类FrameOneInit所在的程序集目录添加进去。
protected override void ConfigureAggregateCatalog()
{
base.ConfigureAggregateCatalog();
//加载自己
this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));
this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(FrameOneInit).Assembly));
}
注:采用 view = this.container.GetExportedValue<具体VIEW类>();或view = ServiceLocator.Current.GetInstance(typeof(类));时系统会报错,原因是采用此种方法的时候,具体的VIEW类是按OBJECT类型抛出的,所以 只能用view = this.container.GetExportedValue<Object>();或view = ServiceLocator.Current.GetInstance(typeof(Objec));获取具体的VIEW类,但是如果采用此种方法的VIEW类不只一个时,会报错。所以只能采用以下方法获取具体的VIEW类
var myList = container.GetExports<object, IViewRegionRegistration>();
foreach (Lazy<object, IViewRegionRegistration> lazy in myList)
{
if (lazy.Value.ToString() =="FrameOne.Views.FrameOneView")
{
view = lazy.Value as FrameOneView;
}
}