5 votes

Le ViewModel doit-il avoir des DependencyProperties pass-through qui se lient aux DependencyProperties du Model ?

Je suis novice en matière de WPF/MVVM et les exemples que j'ai trouvés ne semblent pas couvrir un problème auquel je suis confronté.

J'ai un écran pour gérer un objet de configuration commerciale assez complexe. En MVVM, je pense que cela signifie que je devrais avoir ce qui suit :

  1. Une vue XAML avec une logique proche de zéro.
  2. Une classe ViewModel qui contient la logique de l'écran.
  3. Mes classes d'entreprise habituelles remplissent le rôle de modèle et ont toute la logique d'entreprise.

Dans ma situation, il existe des règles de gestion qui stipulent que les modifications apportées au champ A de ma classe métier peuvent avoir divers effets secondaires, par exemple modifier la valeur du champ B ou remplir une liste entière de sous-objets.

Je peux me tromper, mais je pense que je devrais garder ces règles encapsulées dans la classe métier, car ces règles ne concernent pas tant l'écran que l'entité.

Naturellement, ces effets secondaires doivent immédiatement revenir à l'écran.

Ainsi, du point de vue de l'utilisateur, il peut modifier le champ A et voir le champ B mis à jour dans la vue.

Je comprends comment lier les données de la vue au modèle de vue.

Mais dans mon cas, il semble que j'ai besoin de deux couches de liaison de données : une entre la vue et le ViewModel, et une autre entre le ViewModel et le Modèle.

Étant donné que j'ai essentiellement le même problème deux fois, je pense qu'une seule solution devrait s'appliquer. J'ai donc transformé ma classe Modèle en un DependencyObject, et j'ai transformé ses propriétés en DependencyProperties.

Si l'on considère le champ A par exemple, il apparaît dans les trois couches :

  1. Vue comme un composant visuel lié à ViewModel.FieldA, par exemple text="{Binding FieldA, Mode=TwoWay}".
  2. ViewModel comme propriété de dépendance liée "en haut" à la vue, et "en bas" au modèle.
  3. Modèle comme propriété de dépendance

Je préfère ne pas coupler directement ma vue XAML à l'objet métier en sautant la partie 2, cela ne me semble pas être une application propre du modèle. Peut-être est-ce une erreur.

Il semble que j'aie essentiellement besoin d'une "propriété de dépendance intermédiaire" dans mon ViewModel.

Mes questions :

  • Est-ce la bonne approche générale ou est-ce que je me trompe ?
  • Existe-t-il des exemples d'utilisation de cette approche ?
  • Quelqu'un peut-il donner un exemple de code de la bonne façon de créer une liaison pass-through entre le ViewModel et le Model FieldA DependencyProperties ?

1voto

Steve Py Points 2155

J'ai moi-même été confronté à ce problème, et j'imagine qu'il s'agit d'un accroc très courant lorsqu'il s'agit de MVVM. Ma réponse a été d'éviter de polluer le domaine par des DependencyObject o INotifyPropertyChanged car cela annule quelque peu la validité de l'utilisation d'un ViewModel.

Le but d'un ViewModel est d'exposer un modèle d'une manière qui soit pertinente pour une vue particulière. Cela devient confus lorsque la VM doit essentiellement exposer un objet de domaine entier. Je les appelle les modèles de vue "éditeur". Ce sont les plus tentants pour faire passer les propriétés de l'objet de domaine. Dans ces cas, je donne à la VM une référence à un objet de domaine (composition) et je fais passer des getters et des setters. Le ViewModel adopte INotifyPropertyChanged y IDataErrorInfo plutôt que DependencyProperty pour signaler à l'interface utilisateur si celle-ci doit être rafraîchie ou afficher des erreurs de validation. Si le domaine soulève une erreur de validation, la VM l'attrape et la prépare dans les détails de l'information sur l'erreur de données pour la vue.

0voto

Dave Clemmer Points 2448

Je suis d'accord avec Steve pour dire que vous devriez éviter d'utiliser DependencyObject y DependencyProperty dans vos classes de modèle/domaine, et les classes de modèle de vue devraient adopter INotifyPropertyChanged y IDataErrorInfo à des fins de liaison.

J'ajouterais que dans vos classes de modèle de vue, j'éviterais d'utiliser DependencyProperty sauf pour les propriétés que vous devez utiliser dans la logique du xaml, telles que DataTrigger s.

Pour gérer les changements qui sont déclenchés dans une classe de couche de modèle, j'aurais également une référence à l'objet modèle/domaine dans la classe de modèle de vue, et je passerais par des getters et setters à la classe modèle/domaine comme Steve l'a mentionné. J'ajouterais que la classe modèle/domaine devra lever un événement auquel la classe modèle de vue devra souscrire, de sorte que OnPropertyChanged() pour une ou plusieurs propriétés peut être appelée dans votre classe de modèle de vue en fonction d'un changement survenu dans votre logique métier.

0voto

ColinE Points 36907

Tout d'abord, je ne recommande pas l'utilisation de propriétés de dépendance (DP) pour les modèles de vue ou les modèles. Les DP sont des propriétés qui ont été conçues avec des concepts d'interface utilisateur à l'esprit, comme les règles de préséance, DataContext support, valeurs par défaut et plus encore. Vous n'avez pas besoin de ces concepts au sein d'un modèle de vue, vous devriez donc utiliser INotifyPropertyChanged à la place.

Avoir un modèle de vue qui est simplement un passage vers une couche de modèle. n'apporte aucune valeur ajoutée . Alors ne le faites pas ! Vous ne devriez jamais ajouter des couches, des structures ou des concepts à votre code juste parce que vous pensez que vous devriez le faire. La simplicité est un objectif que vous devez toujours viser.

Donc, si vous pouvez mettre en œuvre une couche de modèle, avec INotifyPropertyChanged il suffit de le lier à votre vue.

Cependant ... dans certains cas, il se peut que vous ne puissiez pas mettre en œuvre les mesures suivantes INotifyPropertyChanged dans votre modèle. Il peut être généré à partir d'un service web par exemple. Dans ce cas, vous aurez besoin d'un modèle de vue qui exécute la fonctionnalité de passage, mais qui ajoute également une notification de changement via le bouton INotifyPropertyChanged .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X