Prism - 如何使用MEF在ViewModel中导入IRegionManager

时间:2012-03-20 15:41:03

标签: wpf prism prism-4

我们如何使用MEF容器在ViewModel中注入IRegionManager。我必须在我的ViewModel的Command委托中切换视图。以下是我正在做的事情的简要说明。我有一个名为Product的实体,其列表显示在一个View(ProductListView)中。在该视图中,用户可以选择产品并单击“编辑”按钮。这将切换视图并呈现新的View(ProductEditView)。为了激活不同的视图,我需要一个像这样的IRegionManager的引用

public class ProductListVM : NotificationObject { //The Product List View Model
    [Import]
    public IRegionManager RegionManager { get; set; }

    private void EditProduct() { //EditCommand fired from ProductListView
        IRegion mainContentRegion = RegionManager.Regions["MainRegion"];
        //Switch the View in "MainContent" region.
        ....
    }
}

上面的代码因RegionManager的NullReferenceException而失败。这似乎是合乎逻辑的,因为上面的View Model是由WPF通过Xaml中的DataContext属性构造的,并且DI没有发挥作用,因此它没有机会导入RegionManager实例。在这种情况下,我们如何解决IRegionManager。

2 个答案:

答案 0 :(得分:5)

可以使用以下

在引导程序中导出Container实例
    container.ComposeExportedValue<CompositionContainer>(container);

然后在viewmodel中,可以使用代码

导入IRegionManager实例
    IServiceLocator serviceLocator = ServiceLocator.Current;
    CompositionContainer container = serviceLocator.GetInstance<CompositionContainer>();
    RegionManager = container.GetExportedValue<IRegionManager>();

但是,在ViewModel中引用View是违反MVVM模式的。但是因为我正在追踪一篇文章here来学习棱镜,所以我不得不相处。这篇文章也在Silverlight中,我必须找到一种在wpf中导入RegionManager的方法,这有点不同。

的问候, NIRVAN。

答案 1 :(得分:1)

尝试使用[ImportingConstructor],如下所示:

public class ProductView : Window
{
  private IProductViewModel viewModel;


   [ImportingConstructor]
   public ProductView(IProductViewModel ViewModel)
   {
       this.viewModel = ViewModel;
       this.DataContext = this.viewModel;
   }
}


public class ProductViewModel: IProductViewModel, INotifyPropertyChanged
{
   private IRegionManager regionManager;
   private ICommand editUserCommand;

   [ImportingConstructor]
   public ProductViewModel(IRegionManager InsertedRegionManager)
   {
      this.regionManager = InsertedRegionManager;
      editUserCommand = new DelegateCommand(ExecuteEditUserCommand, CanExecuteEditUserCommand);
   }

   public ICommand EditUserCommand
   {
       get {return this.editUserCommnad;}
   }

   private bool CanExecuteEditUserCommand()
   {
      return true;
   }

   private void ExecuteEditUserCommand()
   {
      this.regionManager......
   }

}