MVVM - propagation ViewModel après mise à jour Model

Traitée MVVM - propagation ViewModel après mise à jour Model

  • jeudi 22 septembre 2011 13:43
     
     
    Bonjour à tous,

    voilà mon problème : j'ai une liste de clients (listbox rattachée à ListeClientsViewModel), quand je selectionne un client, j'ai un tabcontrol qui m'ouvre un onglet (rattaché à TabItemViewModel) avec comme entete le nom du client et dans cette onglet j'ai un usercontrol (rattaché à ClientViewModel) qui contient les champs pour modifier, entre autre, le nom du client.

    Maintenant quand je modifie le nom du client et que j'enregistre, j'aimerai que ce nouveau nom soit propagé à mes autres viewmodel (mon onglet et à ma liste)...les 2 devant afficher le nouveau nom...

    Quel est la meilleur méthode pour réaliser cela ? 

    Merci de votre aide

Toutes les réponses

  • jeudi 22 septembre 2011 18:58
    Modérateur
     
     Réponse proposée

    Bonjour,

    Deux solutions :

    • Utilisez le mécanisme de Messenger de MVVM Light afin de propager l'information de la modification du nom vers les autres ViewModel (les autres ViewModel doit s'abonner à cet événement). => Avantage : Faible couplage. Inconvénients : plus difficile à tester et s'y retrouver dans le code
    • Le ClientViewModel offre des événements qui permettront au ViewModel (ListeClientsViewModel) parent de s'abonner. => Avantage : Solution plus objet et plus simple à comprendre. Inconvénients : Couplage entre ListeClientsViewModel -> ClientViewModel

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte .NET/Consultant/Formateur chez Winwise
    Blog : http://gilles.tourreau.fr
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5
  • jeudi 22 septembre 2011 20:17
    Modérateur
     
     Réponse proposée
    Ou encore: utiliser la même référence d'objet métier pour contenir les données.
    Jonathan ANTOINE - http://wpf-france.fr - http://www.jonathanantoine.com
  • jeudi 22 septembre 2011 20:22
     
     

    Utiliser le MEssenger ou transmettre les ViewModel aux autres ViewModel, j'y pensais aussi finalement... par contre "utiliser la même référence d'objet métier pour contenir les données." je ne vois pas très bien ce que c'est... peux tu détailler ?

     

    Merci

  • jeudi 22 septembre 2011 20:26
    Modérateur
     
     Réponse proposée
    Imaginons que tu as un objet ClientViewModel contenant les informations de ton client. Tu peux très bien afficher la même instance de cet objet dans la liste et dans la vue de détail. Dans ce cas la, si tu le modifies à un endroit, il est modifié partout.

    Pour info, cela peut aussi être fait via un méchanisme de cache: ton service d'obtention d'un client te renvoit soit ce qu'l va chercher en base de données  soit une instance qu'il a déjà été recherché. Dans ce cas, si tu l'appelles deux fois (dans deux viewModel différents), tu auras deux fois la même instance de ton objet...
    Jonathan ANTOINE - http://wpf-france.fr - http://www.jonathanantoine.com
  • jeudi 22 septembre 2011 20:48
     
     

    Mon objet "Client" est deja transmis de viewmodel en viewmodel... c'est le même objet... par contre si je modifie mon objet "Client" dans un viewmodel, rien ne dis que l'affichage doit être mis à jour dans les autre viewmodel... il faudrai un systeme avec INotifyChanged sur mon objet Client... est ce judicieux ? tout mes ViewModel s'abonneraient à la modification du nom du client par exemple... est ce réalisable ? si oui comment ?

     

    (pour infos, pour mes objets "Model" j'utilise entity framework :

     - projet DAL qui contient le edmx et le fichier clientDAL

     - projet Model qui contient le .tt et la définition de ma classe Client)

  • vendredi 23 septembre 2011 08:09
     
     

    L'utilisation du messager de MVVM tollkit light me plait bien, cependant, si mes tabItemViewModel s'abonne aux messages de mise à jour du titre, si j'ai 3 onglets (donc 3 tabItemViewModel) etque je modifie seulement 1 CLient et que j'enregistre, tous les autres onglet recevront aussi le message et feront une mise à jour pour rien au final...

    Existe t'il une meilleurs solution que de vérifier, pour chaque TabItemViewModel, si c'est celui qui est selectionné  avant de mettre  jour le titre ? ?

    (Du coup l'utilisation d'une référence vers mon TabItemViewModel dans mon usercontrol résoudrait ce problème...)

  • vendredi 23 septembre 2011 08:34
     
     Réponse proposée

    L'approche de Jonathan me parait bien. Tu dois définir un service centrale qui :

      1/ contient un cache (de Client),

      2/ expose des methodes pour la manipulation des objets

      3/ espose un event pour notifier les objets.

    Enusite il faudra implémenter deux ViewModels : ClientCollectionViewModel et ClientViewModel. Les ViewModel doivent implémenter l'interface INotifyPropertyChanged.

    Ensuite ClientCollectionViewModel doit consomer le service centrale et s'abonner à l'event qu'il expose. Ce ViewModel contiendra aussi son cache local, qui servira pour le binding avec la view, et donc tu dois implémenter ta logique d'ajout suppréssion des objets qui viennet du service.

    De cette façon tous les ViewModels qui consomment le service centrale, et s'abonnent à l'event qu'expose ce service auront des données cohérentes.

    P.S. pour l'abonnement au cache du service, tu pourrait utiliser la librairie (si tu es en .Net 3.5) ReactiveExtention au lieu d'utiliser les events.

     


    PhD - Student

  • vendredi 23 septembre 2011 09:52
    Modérateur
     
     Réponse proposée

    Bonjour,

     

    oui tu peux passer l'id du client modifié et bien vérifier qu'il y a correspondance :)

     

    Bon courage,


    Jonathan ANTOINE - http://wpf-france.fr - http://www.jonathanantoine.com
  • samedi 24 septembre 2011 06:34
    Modérateur
     
     

    Bonjour,

    Est-ce que vous avez testé les solutions proposées ? Merci de partager avec nous les résultats,afin que d'autres personnes avec le même problème puissent profiter de cette solution.


    Cordialement, Pascal.

    Développeur Wpf/SilverLight/WinPhone7

  • lundi 26 septembre 2011 07:36
     
     Traitée

    En fait, je veux que les modifications ne soient propagées au TabItem et à ma liste seulement si j'appui sur "Enregistrer", j'ai donc préféré utiliser le Messenger : quand j'appui sur "Enregistrer", je vérifie le nom saisie puis je l'enregistre et j'envoie le message de modification...

    • Marqué comme réponse CaptainChoc lundi 26 septembre 2011 07:48
    •  
  • lundi 26 septembre 2011 07:47
    Modérateur
     
     
    C'est parfait comme cela, un cas d'école du Messenger :)
    Jonathan ANTOINE - http://wpf-france.fr - http://www.jonathanantoine.com