How the ViewModel communicate with the RegionManager to Register a view (detailRegion) ?

Topics: Prism v2 - Silverlight 3, Prism v2 - Silverlight 4, Prism v4 - Silverlight 4
Jan 7, 2011 at 3:08 PM

Hi, i met this problem

I have a shell with 2 regions : the MainRegion and the DetailRegion :

<ItemsControl x:Name="MainRegion" Regions:RegionManager.RegionName="MainRegion" Background="AliceBlue">
</ItemsControl>
<ItemsControl x:Name="DetailRegion" Regions:RegionManager.RegionName="DetailRegion" Background="Azure">
</ItemsControl>

I have 2 modules : ModuleA et ModuleB loaded in the Catalog :

ModuleCatalog catalog = new ModuleCatalog();
catalog.AddModule(typeof(ModuleA.ModuleA));
catalog.AddModule(typeof(ModuleB.ModuleB));

The Initialize() of the ModuleA register the ModuleAView to the MainRegion
void IModule.Initialize()
{
   _container.RegisterType<ICompanyService, CompanyService>();
   _regionManager.RegisterViewWithRegion("MainRegion", typeof(ModuleAView));
}  

This ModuleAView shows a list of data binded to the ModuleAViewModel
The selectedItem of that list is binded to a property SelectedItem of the ModuleAViewModel :
SelectedItem="{Binding SelectedCompany}” 

Once an item is selected the property “SelectedCompany” is raised. It’s ok.

NOW… the questions is:

I would like to show the detail of this selectedItem in the DetailRegion,
But the ModuleAViewModel don’t have any reference of the RegionManager in order to push data selected with the view to the DetailRegion.


How can we do ?
CAG-Quickstart uses the Controller, a kind of superclass that manage all of this.
Is this only way to do ?

thanks.

Developer
Jan 7, 2011 at 4:24 PM

Hi,

You can also obtain a reference to the Region Manager in your ViewModel through dependency injection. For example, if you're using MEF and you'd like to achieve constructor injection in your ViewModel, you could have something like this:

 

[Export]

public class ModuleAViewModel
{
(...)
private IRegionManager regionManager;

  [ImportingConstructor]
  public ModuleAViewModel(IRegionManager regionManager)
  {
    this.regionManager=regionManager;
  }
(...)
}

Take into account that, in order for your ViewModel to obtain a reference to the Region Manager, it must be composed by MEF, so you should do something like this in your view:

[Export]
public partial class ModuleAView : UserControl
{
(...)
  [ImportingConstructor]
  public ModuleAView(ModuleAViewModel viewModel)
  {
    InitializeComponent();
    this.DataContext = viewModel;
  }
(...)
}
I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jan 7, 2011 at 4:48 PM

Well you could use a controller or you could use IEventAggregator and publish as the payload of the event to the DetailsViewModel.  In my app, I actually figured out that I needed a combination of the 2, IEventAggregator and a Controller.  At one point I was doing alot of the initial work in the module file, realized later that a controller was ideal for the work being done.

So 2 events I do... 1 new flight event (raised from mainmenu) and edit flight event (raised from a datagrid context menu).  The only thing I am passing though is the integer of the flight id,  in the case of the new flight I pass 0, so my payload for the CompositePresentationEvent<T> is int.

The one thing that I am using though is the RegionManager in my viewmodels, it is primarily needed for the Context.  Allows me to get the passed value.