2010-08-20 15 views
0

J'écris une application WPVM MVF en utilisant Prism. Il y a quelques jours, j'ai posé des questions sur les meilleures pratiques pour gérer différents points de vue et je n'ai pas reçu beaucoup de commentaires. J'ai alors trouvé un système qui semble fonctionner, mais je veux m'assurer que je ne serai pas sur la bonne voie.Est-ce une pratique acceptable de gestion des vues dans une application WPF utilisant Prism?

J'ai suivi les tutoriels au http://development-guides.silverbaylabs.org/ pour obtenir la configuration de mon shell et je suis confiant que mes modules sont bien enregistrés.

Cependant, nulle part dans ces didacticiels, il n'y avait un exemple de vue remplacée par une vue différente dans une région donnée. Ceci en général, semble être assez difficile à trouver un bon exemple de. Donc, aujourd'hui, j'ai roulé ma propre solution au problème. Essentiellement le module a un contrôleur qui garde la trace de la vue courante, puis quand l'utilisateur veut changer de vue, il appelle la commande Regions.Remove et ensuite la commande add pour le remplacer par la vue courante. Il semble qu'il doit y avoir une solution plus élégante pour basculer entre différentes vues enregistrées, mais je ne l'ai pas trouvé.

Toutes les différentes vues possibles pour un module sont enregistrées avec le conteneur Unity lorsque le module est initialisé.

Le dispositif de commande et la fonction de commutation de vue suivante:

namespace HazardModule 
{ 
    public class HazardController : IHazardController 
    { 

     private object CurrentView; 
     public IRegionManager RegionManager { get; set; } 
     private IUnityContainer _container; 

     public HazardController(IUnityContainer container) 
     { 
      _container = container; 
     } 

     /// <summary> 
     /// Switches the MainRegion view to a different view 
     /// </summary> 
     /// <typeparam name="T">The class of the view to switch to</typeparam> 
     public void SiwthToView<T>() 
     { 
      if (CurrentView != null) 
      { 
       RegionManager.Regions["MainRegion"].Remove(CurrentView); 
      } 
      CurrentView = _container.Resolve<T>(); 
      RegionManager.Regions["MainRegion"].Add(CurrentView); 
     } 

    } 
} 

Tous les commentaires ou d'autres meilleures solutions seraient appréciés.

Répondre

1

J'ai à peu près la même approche, tout comme un collègue qui a un peu plus d'expérience avec le prisme que moi-même.

Fondamentalement, j'ai une classe ViewController qui est une propriété dans ma classe ViewModelBase. Cela permet à tous mes ViewModels d'y avoir accès en une fois. Ensuite, dans ma classe ViewController, j'ai quelques méthodes de gestion d'affichage. La justesse de cette approche est probablement discutable, mais je l'ai trouvé très bien fonctionner dans mon cas

public TView ShowViewInRegion<TView>(string regionName, string viewName, bool removeAllViewsFromRegion) 
    { 
     var region = regionManager.Regions[regionName]; 

     var view = region.GetView(viewName) ?? container.Resolve<TView>(); 

     if (removeAllViewsFromRegion) 
     { 
      RemoveViewsFromRegion(region); 
     } 

     region.Add(view, viewName); 
     region.Activate(view); 

     if (regionName == RegionNames.OverlayRegion) 
     { 
      eventAggregator.GetEvent<PopupWindowVisibility>().Publish(true); 
     } 

     return (TView)view; 
    } 

    public void RemoveViewsFromRegion(string regionName) 
    { 
     RemoveViewsFromRegion(regionManager.Regions[regionName]); 
    } 

    private void RemoveViewsFromRegion(IRegion region) 
    { 
     for (int i = 0; i < region.Views.Count() + i; i++) 
     { 
      var view = region.Views.ElementAt(0); 
      region.Remove(view); 
     } 

     if (region.Name == RegionNames.OverlayRegion) 
     { 
      eventAggregator.GetEvent<PopupWindowVisibility>().Publish(false); 
     } 
    } 

    private static void DeactivateViewsInRegion(IRegion region) 
    { 
     for (var i = 0; i < region.ActiveViews.Count(); i++) 
     { 
      var view = region.ActiveViews.ElementAt(i); 
      region.Deactivate(view); 
     } 
    } 

Ensuite, chaque fois que je dois passer à une vue ou tout ce que je peux appeler de mon ViewModel

public void ExecuteCreateUserCommand() 
    { 
     ViewController.ShowViewInRegion<IUserCreateView>(RegionNames.ContentRegion, ViewNames.UserCreateView, true); 
    }