C# PRISM:如何将视图模型添加到区域并自动创建视图?
我对PRISM还不熟悉,还尝试了一些东西。我和MVVM有点纠结 将视图与viewmodel“连接”的方式很清楚:C# PRISM:如何将视图模型添加到区域并自动创建视图?,c#,wpf,mvvm,prism,C#,Wpf,Mvvm,Prism,我对PRISM还不熟悉,还尝试了一些东西。我和MVVM有点纠结 将视图与viewmodel“连接”的方式很清楚: 通过统一注入,或 手动设置数据上下文(ServiceLocator) 如果我将视图添加到区域(viewmodel是自动创建的),则一切正常。但这不是用例 让我们来看一个例子: public class MyViewModel : NotificationObject { public ObservableCollection<AnotherViewModel>
- 通过统一注入,或
- 手动设置数据上下文(ServiceLocator)
public class MyViewModel : NotificationObject
{
public ObservableCollection<AnotherViewModel> OrderModel { get; private set; }
}
公共类MyViewModel:NotificationObject
{
我必须为视图和视图模型(iOnotherViewModel,iOnotherView)创建自己的接口
这里可以找到另一种方法:是否有任何理由不为此使用隐式
数据模板
它们是定义数据类型
属性的数据模板
,但不是键
属性,并且在WPF尝试绘制指定数据类型的对象时使用它们
比如说,
<TabControl ItemsSource="{Binding MyViewModelCollection}"
SelectedItem="{Binding SelectedViewModel}">
<!-- This could also go elsewhere, like Application.Resources -->
<TabControl.Resources>
<DataTemplate DataType="{x:Type local:ViewModelA}">
<local:ViewA />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelB}">
<local:ViewB />
</DataTemplate>
</TabControl.Resources>
</TabControl>
如果选项卡控件
正在显示类型为ViewModelA
的对象,它将使用ViewModelA
进行绘制,如果它正在显示ViewModelB
,它将使用ViewB
进行绘制是否有任何理由不为此使用隐式数据模板
它们是定义数据类型
属性的数据模板
,但不是键
属性,并且在WPF尝试绘制指定数据类型的对象时使用它们
比如说,
<TabControl ItemsSource="{Binding MyViewModelCollection}"
SelectedItem="{Binding SelectedViewModel}">
<!-- This could also go elsewhere, like Application.Resources -->
<TabControl.Resources>
<DataTemplate DataType="{x:Type local:ViewModelA}">
<local:ViewA />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelB}">
<local:ViewB />
</DataTemplate>
</TabControl.Resources>
</TabControl>
如果选项卡控件
正在显示类型为ViewModelA
的对象,它将使用ViewModelA
进行绘制,如果它正在显示ViewModelB
,它将使用ViewB进行绘制。如果您正在使用MEF,则可以使用属性自动进行视图注册:
/*YOUR VIEW*/
[ExportViewToRegion("MyView", "MyRegion")]
[Export(typeof(MyView))]
public partial class MyView : UserControl
{
....
}
/*IMPLEMENTATION*/
public interface IExportViewToRegionMetadata
{
string ViewName { get; }
string TargetRegion { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false)]
public class ExportViewToRegionAttribute : ExportAttribute
{
public ExportViewToRegionAttribute(string viewName, string targetRegion)
: base(typeof(UserControl))
{
ViewName = viewName;
TargetRegion = targetRegion;
}
public string ViewName { get; private set; }
public string TargetRegion { get; private set; }
}
[Export(typeof(IFluentRegionManager))]
public class FluentRegionManager : IFluentRegionManager, IPartImportsSatisfiedNotification
{
public IRegionManager RegionManager { get; set; }
[ImportingConstructor]
public FluentRegionManager(IRegionManager regionManager)
{
RegionManager = regionManager;
}
/*This Import will find all views in the assembly with attribute [ExportViewToRegion("ViewName", "RegionName")]*/
[ImportMany(AllowRecomposition = true)]
public Lazy<UserControl, IExportViewToRegionMetadata>[] Views { get; set; }
private readonly List<string> _processedViews = new List<string>();
private Lazy<UserControl, IExportViewToRegionMetadata> _GetViewInfo(string viewName)
{
return (from v in Views where v.Metadata.ViewTypeForRegion.Equals(viewName) select v).FirstOrDefault();
}
public IExportViewToRegionMetadata this[string viewName]
{
get
{
return (from v in Views
where v.Metadata.ViewName.Equals(viewName, StringComparison.InvariantCultureIgnoreCase)
select v.Metadata).FirstOrDefault();
}
}
public void ExportViewToRegion(string viewName)
{
if (viewName==null)
{
throw new ArgumentNullException("viewName");
}
var viewInfo = _GetViewInfo(viewName);
string targetRegion;
UserControl _view;
if (viewInfo != null)
{
targetRegion = viewInfo.Metadata.TargetRegion;
_view = viewInfo.Value;
}
if (string.IsNullOrEmpty(targetRegion) || _processedViews.Contains(viewName)) return;
RegionManager.RegisterViewWithRegion(targetRegion, _view.GetType());
_processedViews.Add(viewName);
}
/*All required views has been discovered and imported */
/*Loop true collection and register view with the region */
public void OnImportsSatisfied()
{
foreach (var viewName in from view in Views where !_processedViews.Contains(view.Metadata.ViewName)
select view.Metadata.ViewName)
{
ExportViewToRegion(viewName);
}
}
}
/* finally call IFluentRegionManager import in the bootstrapper to kick off registration*/
/*您的视图*/
[ExportViewToRegion(“MyView”、“MyRegion”)]
[导出(typeof(MyView))]
公共部分类MyView:UserControl
{
....
}
/*实施*/
公共接口IExportViewToRegionMetadata
{
字符串ViewName{get;}
字符串TargetRegion{get;}
}
[元数据属性]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property,AllowMultiple=false)]
公共类ExportViewToRegionaAttribute:ExportAttribute
{
公共ExportViewToRegionaAttribute(字符串viewName、字符串targetRegion)
:base(typeof(UserControl))
{
ViewName=ViewName;
TargetRegion=TargetRegion;
}
公共字符串ViewName{get;private set;}
公共字符串TargetRegion{get;private set;}
}
[导出(类型(IFluentRegionManager))]
公共类FluentRegion管理器:iFluentRegion管理器、iPartimportsAssetFiedNotification
{
公共IRegionManager区域管理器{get;set;}
[导入构造函数]
公共FluentRegionManager(IRegionManager regionManager)
{
RegionManager=RegionManager;
}
/*此导入将查找具有属性[ExportViewToRegion(“ViewName”、“RegionName”)]的程序集中的所有视图*/
[进口数量(AllowRecomposition=true)]
公共惰性[]视图{get;set;}
私有只读列表_processedViews=new List();
private Lazy\u GetViewInfo(字符串viewName)
{
返回(从视图中的v返回,其中v.Metadata.ViewTypeForRegion.Equals(viewName)选择v).FirstOrDefault();
}
公共IExportViewToRegionMetadata此[字符串视图名称]
{
收到
{
返回(从视图中的v)
其中v.Metadata.ViewName.Equals(ViewName、StringComparison.InvariantCultureIgnoreCase)
选择v.Metadata).FirstOrDefault();
}
}
public void ExportViewToRegion(字符串viewName)
{
if(viewName==null)
{
抛出新的ArgumentNullException(“viewName”);
}
var viewInfo=_GetViewInfo(viewName);
字符串目标区域;
用户控制视图;
如果(视图信息!=null)
{
targetRegion=viewInfo.Metadata.targetRegion;
_视图=视图信息值;
}
if(string.IsNullOrEmpty(targetRegion)| | | u processedViews.Contains(viewName))返回;
RegionManager.RegisterViewWithRegion(targetRegion,_view.GetType());
_processedViews.Add(视图名称);
}
/*已发现并导入所有必需的视图*/
/*使用区域循环true集合和register视图*/
公共无效OnImportsAssetized()
{
foreach(视图中的from视图中的var viewName,其中!\u processedViews.Contains(view.Metadata.viewName)
选择view.Metadata.ViewName)
{
ExportViewToRegion(视图名称);
}
}
}
/*最后在引导程序中调用IFluentRegionManager导入以开始注册*/
如果您正在使用MEF,那么您可以使用属性自动进行视图注册:
/*YOUR VIEW*/
[ExportViewToRegion("MyView", "MyRegion")]
[Export(typeof(MyView))]
public partial class MyView : UserControl
{
....
}
/*IMPLEMENTATION*/
public interface IExportViewToRegionMetadata
{
string ViewName { get; }
string TargetRegion { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false)]
public class ExportViewToRegionAttribute : ExportAttribute
{
public ExportViewToRegionAttribute(string viewName, string targetRegion)
: base(typeof(UserControl))
{
ViewName = viewName;
TargetRegion = targetRegion;
}
public string ViewName { get; private set; }
public string TargetRegion { get; private set; }
}
[Export(typeof(IFluentRegionManager))]
public class FluentRegionManager : IFluentRegionManager, IPartImportsSatisfiedNotification
{
public IRegionManager RegionManager { get; set; }
[ImportingConstructor]
public FluentRegionManager(IRegionManager regionManager)
{
RegionManager = regionManager;
}
/*This Import will find all views in the assembly with attribute [ExportViewToRegion("ViewName", "RegionName")]*/
[ImportMany(AllowRecomposition = true)]
public Lazy<UserControl, IExportViewToRegionMetadata>[] Views { get; set; }
private readonly List<string> _processedViews = new List<string>();
private Lazy<UserControl, IExportViewToRegionMetadata> _GetViewInfo(string viewName)
{
return (from v in Views where v.Metadata.ViewTypeForRegion.Equals(viewName) select v).FirstOrDefault();
}
public IExportViewToRegionMetadata this[string viewName]
{
get
{
return (from v in Views
where v.Metadata.ViewName.Equals(viewName, StringComparison.InvariantCultureIgnoreCase)
select v.Metadata).FirstOrDefault();
}
}
public void ExportViewToRegion(string viewName)
{
if (viewName==null)
{
throw new ArgumentNullException("viewName");
}
var viewInfo = _GetViewInfo(viewName);
string targetRegion;
UserControl _view;
if (viewInfo != null)
{
targetRegion = viewInfo.Metadata.TargetRegion;
_view = viewInfo.Value;
}
if (string.IsNullOrEmpty(targetRegion) || _processedViews.Contains(viewName)) return;
RegionManager.RegisterViewWithRegion(targetRegion, _view.GetType());
_processedViews.Add(viewName);
}
/*All required views has been discovered and imported */
/*Loop true collection and register view with the region */
public void OnImportsSatisfied()
{
foreach (var viewName in from view in Views where !_processedViews.Contains(view.Metadata.ViewName)
select view.Metadata.ViewName)
{
ExportViewToRegion(viewName);
}
}
}
/* finally call IFluentRegionManager import in the bootstrapper to kick off registration*/
/*您的视图*/
[ExportViewToRegion(“MyView”、“MyRegion”)]
[导出(typeof(MyView))]
公共部分类MyView:UserControl
{
....
}
/*实施*/
公共接口IExportViewToRegionMetadata
{
字符串ViewName{get;}
字符串TargetRegion{get;}
}
[元数据属性]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property,AllowMultiple=false)]
公共类ExportViewToRegionaAttribute:ExportAttribute
{
公共出口vi