Meerdere soorten Views in PRISM

image In deze post ga ik het hebben over een probleem waar ik tegen aan ben gelopen bij het gebruik van Prism. Deze techniek wordt toegepast in Silverlight -waarin wij werken- maar ook in WPF applicaties. Deze techniek zorgt er voor dat de verschillende delen van de applicatie losgekoppeld worden en daarmee makkelijk te veranderen of te hergebruiken zijn. Voor meer informatie over Prism ga naar http://compositewpf.codeplex.com/ of volg de goede tutorial van Channel9 hier: http://channel9.msdn.com/posts/akMSFT/Creating-a-modular-application-using-Prism-V2-Part-1-of-4--Creating-a-shell-and-modules/.

Het probleem
Wanneer ik in Prism verschillende Regions defineer en daar views in stop, kan ik niet de lay-out van mijn applicatie drastisch veranderen per scherm.  Neem bijvoorbeeld deze lay-out:

image

Wat als ik nou een loginscherm wil hebben waarbij bijvoorbeeld linksboven het login gedeelte zit en in het midden een news feed? Dan moeten mijn regions wel heel anders gedefinieerd zijn dan hierboven het geval is. Na een tijdje hiermee gestoeid te hebben ben ik tot de volgende oplossing gekomen.

De oplossing

Eerst heb ik een full screen region gemaakt in de shell.xaml. Dit is de enige region in de Shell.

<ContentControl regions:RegionManager.RegionName="FullScreen"
  VerticalContentAlignment="Stretch"
  HorizontalContentAlignment="Stretch">
</ContentControl>

 

Wanneer de applicatie opstart registreer ik de Welcome view met het fullscreen region:

m_regionManager.RegisterViewWithRegion(Regions.FullScreen.ToString(), () =>
   m_container.Resolve<ViewWelcome>());

 

De ViewWelcome heeft zijn eigen regions voor het login scherm, zoals ik boven beschreven heb.

Wanneer de gebruiker is ingelogd, deactiveer ik het Welcome scherm en activeer ik het Main scherm, deze bevat alle andere regions zoals boven in het plaatje te zien is. Ik doe dit in de Shell.xaml.cs codebehind, door me te subscriben aan een event door gebruik te maken van de eventaggregator zoals hier in de constructor:

m_regionManager.RegisterViewWithRegion(Regions.FullScreen.ToString(), () => 
  m_container.Resolve<ViewWelcome>());

 

En dit is de method die gebruikt wordt om tussen de views te wisselen:

private void switchViewsEventHandler(string viewSetName)
{
  switch (viewSetName.ToLower())
  {
    case "login":
      RegionViewManager.DeactivateView(         
         m_regionManager.Regions[Regions.FullScreen.ToString()],
           typeof(ViewMain));
      RegionViewManager.AddAndActivateView(
         m_regionManager.Regions[Regions.FullScreen.ToString()],
           typeof(ViewWelcome), m_container);
      break;
    case "main":
      RegionViewManager.DeactivateView(
         m_regionManager.Regions[Regions.FullScreen.ToString()],
           typeof(ViewWelcome));
      RegionViewManager.AddAndActivateView(
         m_regionManager.Regions[Regions.FullScreen.ToString()],
           typeof(ViewMain), m_container);
      break;
  }
}

 

Wat hier het interessante is, is waarschijnlijk de deactiveer en activeer methods in de RegionViewManager class, dus die laat ik hier zien.

public static class RegionViewManager
{
  public static void DeactivateView(IRegion region, Type viewType)
  {
    foreach (object view in region.Views)
    {
      if (view.GetType() == viewType)
      {
        region.Deactivate(view);
      }
    }
  }
  public static void AddAndActivateView(IRegion region, Type viewType, 
      IUnityContainer container)
  {
    bool found = false;
    foreach (var existingView in region.Views)
    {
      if(existingView.GetType() == viewType)
      {
        region.Activate(existingView);
        found = true;
        break;
      }
    }
    if (!found)
    {
      var view = container.Resolve(viewType);
      region.Add(view);
      region.Activate(view);
    }
  }
}

 

Om het samen te vatten: eerst activeer ik de Welcome view, die in de fullscreen region zit. Dan, wanneer ik inlog, deactiveer ik de Welcome view en activeer ik de main view, die ook in de Fullscreen region zit. Deze views hebben beide hun eigen regions. Dit maakt het mogelijk om zoveel verschillende layouts voor mijn applicatie te gebruiken als ik wil.

We zijn nog steeds bezig deze technieken te verbeteren. Als je tips hebt, twijfel dan niet te reageren.

Laat een opmerking achter