简体   繁体   中英

Prism - How to import IRegionManager in ViewModel using MEF

How do we inject IRegionManager in the ViewModel using MEF Container. I have to switch view in my ViewModel's Command delegate. Here is the brief description of what I am doing. I have an entity called Product whose list is displayed in one View (ProductListView). In that view the user can select the Product and click on Edit button. This would switch the view and present a new View(ProductEditView). For activating a different view, I would need a reference to IRegionManager something like this

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.
        ....
    }
}

The above code fails with NullReferenceException for RegionManager. This seems logical because the above View Model is constructed by WPF through DataContext property in Xaml and DI doesn't come into play, so it doesn't get a chance to import the RegionManager instance. How do we resolve the IRegionManager in this scenario.

The Container instance can be exported in the bootstrapper using following

    container.ComposeExportedValue<CompositionContainer>(container);

Then in the viewmodel, the IRegionManager instance can be imported using the code

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

However, referring a View in ViewModel is a violation of the MVVM pattern. But since I was following an article here to learn Prism , I had to get along the same. Also the article was in Silverlight and I had to find a way to import RegionManager in wpf, which is little different.

regards, Nirvan.

Try using [ImportingConstructor] like this:

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......
   }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM