ViewModel 未在视图注入时初始化(WPF PRISM 4 MVVM)
我正在使用 PRISM4 MVVM 模式,并且当应用程序启动时,视图已成功加载并显示在适当的区域上。当应用程序启动时,ViewModels 会在视图加载时自动初始化。但是,如果我尝试在新选项卡(新区域)上注入新视图,则新视图的 ViewModel 不会初始化。下面是视图注入的代码:
IRegion region = regionManager.Regions["RegionNameGoesHere"];
var pane = new Views.ABCView() {Tag = id};
regionManager.Regions["RegionNameGoesHere"].Add(pane);
上面的代码打开一个新选项卡并加载新视图,但它不会初始化 ViewModel。控件的每个选项卡都是一个新区域(选项卡控件有一个 RegionAdapter)。
这是视图背后的代码:
using System.ComponentModel.Composition;
using System.Diagnostics.CodeAnalysis;
using System.Windows.Controls;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Docking;
namespace Company.Application.Module.Assembly.Views
{
[Infrastructure.Behaviours.ViewExport("ABCView")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class ABCView : RadPane
{
public ABCView()
{
this.InitializeComponent();
}
/// <summary>
/// Sets the ViewModel.
/// </summary>
/// <remarks>
/// This set-only property is annotated with the <see cref="ImportAttribute"/> so it is injected by MEF with
/// the appropriate view model.
/// </remarks>
[Import]
[SuppressMessage("Microsoft.Design", "CA1044:PropertiesShouldNotBeWriteOnly", Justification = "Needs to be a property to be composed by MEF")]
ABCViewModel ViewModel
{
set
{
this.Decorator.DataContext = value;
//this.DataContext = value;
}
}
}
}
这是带有一些属性和事件的 ViewModel。我在上面的代码中缺少一些初始化下面的 ViewModel 的内容。任何建议都将不胜感激。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel.Composition;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Xml;
using System.Xml.XPath;
using System.Windows.Data;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Prism.ViewModel;
namespace Company.Application.Module.Assembly.Views
{
[Export(typeof(ABCViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ABCViewModel : NotificationObject
{
private readonly IRegionManager regionManager;
[ImportingConstructor]
public ABCViewModel(IRegionManager regionManager)
{
// Event Aggregator
//this.eventAggregator = eventAggregator;
// Region Manager
this.regionManager = regionManager;
}
#region P R O P E R T I E S
#region E V E N T S
}
}
I'm using PRISM4 MVVM Pattern, and the views are loaded successfully and displayed on the appropriate regions when the application starts. When the application starts, the ViewModels are initialized automatically when the view is loaded. However, if I try to inject a new view on a new tab (new region), the ViewModel of the new view is not initialized. Here's the code for view injection:
IRegion region = regionManager.Regions["RegionNameGoesHere"];
var pane = new Views.ABCView() {Tag = id};
regionManager.Regions["RegionNameGoesHere"].Add(pane);
The code above opens a new tab and load the new view, but it doesn't initialize the ViewModel. Each tab of the control is a new region (there's a RegionAdapter for the tab control).
Here's the code behind the view:
using System.ComponentModel.Composition;
using System.Diagnostics.CodeAnalysis;
using System.Windows.Controls;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Docking;
namespace Company.Application.Module.Assembly.Views
{
[Infrastructure.Behaviours.ViewExport("ABCView")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public partial class ABCView : RadPane
{
public ABCView()
{
this.InitializeComponent();
}
/// <summary>
/// Sets the ViewModel.
/// </summary>
/// <remarks>
/// This set-only property is annotated with the <see cref="ImportAttribute"/> so it is injected by MEF with
/// the appropriate view model.
/// </remarks>
[Import]
[SuppressMessage("Microsoft.Design", "CA1044:PropertiesShouldNotBeWriteOnly", Justification = "Needs to be a property to be composed by MEF")]
ABCViewModel ViewModel
{
set
{
this.Decorator.DataContext = value;
//this.DataContext = value;
}
}
}
}
And here's the ViewModel with a few properties and events. I'm missing something in the code above to initialize the ViewModel below. Any suggestion is greatly appreciated.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel.Composition;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Xml;
using System.Xml.XPath;
using System.Windows.Data;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Prism.ViewModel;
namespace Company.Application.Module.Assembly.Views
{
[Export(typeof(ABCViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ABCViewModel : NotificationObject
{
private readonly IRegionManager regionManager;
[ImportingConstructor]
public ABCViewModel(IRegionManager regionManager)
{
// Event Aggregator
//this.eventAggregator = eventAggregator;
// Region Manager
this.regionManager = regionManager;
}
#region P R O P E R T I E S
#region E V E N T S
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是您自己创建视图,而不是让 CompositionContainer 为您创建视图。 CompositionContainer 对您自己创建的对象一无所知,因此当您调用 new Views.ABCView() 时,导入不会神奇地得到满足。
使用原始 MEF,您可以调用 CompositionContainer.GetExports() 从容器中获取视图。 Prism 中可能有一些基础设施围绕此调用,但我对 Prism 不太了解,所以我不知道具体是什么。
The problem is that you are creating the view yourself instead of having the CompositionContainer create it for you. The CompositionContainer doesn't know anything about objects you create yourself, so when you call
new Views.ABCView()
, the imports aren't magically satisfied.With raw MEF, you would call CompositionContainer.GetExports() to get a view from the container. There is probably some infrastructure in Prism that wraps around this call, but I don't know much about Prism so I don't know exactly what that would be.