La plupart des exemples MVVM sur lesquels j'ai travaillé ont eu l' implémentation ModelINotifyPropertyChanged
, mais dans l'exemple CommandSink de Josh Smith, ViewModel implémenteINotifyPropertyChanged
.
Je suis toujours en train de rassembler cognitivement les concepts MVVM, donc je ne sais pas si:
- Vous devez mettre le
INotifyPropertyChanged
dans le ViewModel pour vous mettreCommandSink
au travail - Ce n'est qu'une aberration de la norme et cela n'a pas vraiment d'importance
- Vous devriez toujours avoir le modèle implémenté
INotifyPropertyChanged
et ce n'est qu'une erreur qui serait corrigée si cela était développé à partir d'un exemple de code vers une application
Quelles ont été les expériences des autres sur les projets MVVM sur lesquels vous avez travaillé?
c#
mvvm
inotifypropertychanged
Edward Tanguay
la source
la source
Réponses:
Je dirais plutôt le contraire, je mets toujours mon
INotifyPropertyChanged
sur mon ViewModel - vous ne voulez vraiment pas polluer votre modèle avec une fonctionnalité assez spécifique à WPF commeINotifyPropertyChanged
, ce truc devrait rester dans le ViewModel.Je suis sûr que d'autres ne seraient pas d'accord, mais c'est comme ça que je travaille.
la source
Je suis totalement en désaccord avec le concept selon lequel le modèle ne devrait pas mettre en œuvre le
INotifyPropertyChanged
. Cette interface n'est pas spécifique à l'interface utilisateur! Il informe simplement d'un changement. En effet, WPF l'utilise fortement pour identifier les changements, mais cela ne signifie pas qu'il s'agit d'une interface utilisateur. Je le comparerais au commentaire suivant: " Un pneu est un accessoire de voiture ". Bien sûr, mais les vélos, les bus, etc. l'utilisent également. En résumé, ne considérez pas cette interface comme une interface utilisateur.Cela dit, cela ne signifie pas nécessairement que je pense que le modèle devrait fournir des notifications. En fait, en règle générale, le modèle ne doit pas implémenter cette interface, sauf si cela est nécessaire. Dans la plupart des cas où aucune donnée de serveur n'est transmise à l'application cliente, le modèle peut être obsolète. Mais si j'écoute les données du marché financier, alors je ne vois pas pourquoi le modèle ne peut pas implémenter l'interface. À titre d'exemple, que se passe-t-il si j'ai une logique non-UI telle qu'un service qui, lorsqu'il reçoit une offre ou une demande de prix pour une valeur donnée, émet une alerte (par exemple via un e-mail) ou passe une commande? Cela pourrait être une solution propre possible.
Cependant, il existe différentes manières de réaliser les choses, mais je plaiderais toujours en faveur de la simplicité et éviterais la redondance.
Qu'est-ce qui est mieux? Définir des événements sur une collection ou des modifications de propriété sur le modèle de vue et les propager au modèle ou demander à la vue de mettre à jour intrinsèquement le modèle (via le modèle de vue)?
En fin de compte, chaque fois que vous voyez quelqu'un affirmer que « vous ne pouvez pas faire ceci ou cela », c'est un signe qu'ils ne savent pas de quoi ils parlent.
Cela dépend vraiment de votre cas et en fait MVVM est un framework avec beaucoup de problèmes et je n'ai pas encore vu une implémentation commune de MVVM à tous les niveaux.
J'aurais aimé avoir plus de temps pour expliquer les nombreuses saveurs de MVVM et quelques solutions aux problèmes courants - principalement fournis par d'autres développeurs, mais je suppose que je devrai le faire une autre fois.
la source
INotifyPropertyChanged
fait partie de l'System.ComponentModel
espace de noms qui est pour "le comportement d'exécution et de conception des composants et des contrôles ". NE PAS UTILISERINotifyPropertyChanged
dans les modèles, uniquement dans ViewModels. Lien vers la documentation: docs.microsoft.com/en-us/dotnet/api/system.componentmodelDans MV-VM, le ViewModel implémente toujours (pas toujours le modèle)
INotifyPropertyChanged
Consultez le modèle de projet / boîte à outils MV-VM sur http://blogs.msdn.com/llobo/archive/2009/05/01/download-mv-vm-project-template-toolkit.aspx . Il utilise le
DelegateCommand
pour commander et devrait être un excellent modèle de départ pour vos projets MV-VM.la source
Je pense que MVVM est très mal nommé et appeler le ViewModel un ViewModel fait manquer à beaucoup une caractéristique importante d'une architecture bien conçue, qui est un DataController qui contrôle les données, peu importe qui essaie de le toucher.
Si vous considérez le View-Model comme un DataController et implémentez une architecture dans laquelle votre DataController est le seul élément qui touche les données, vous ne toucherez jamais directement les données, mais utiliserez toujours le DataController. Le DataController est utile à l'interface utilisateur mais pas nécessairement uniquement à l'interface utilisateur. C'est pour la couche métier, la couche d'interface utilisateur, etc.
Vous vous retrouvez avec un modèle comme celui-ci. Même l'entreprise ne doit toucher les données qu'à l'aide du ViewModel. Ensuite, votre énigme disparaît.
la source
Cela dépend de la manière dont vous avez implémenté votre modèle. Mon entreprise utilise des objets métier similaires aux objets CSLA de Lhotka et les utilise largement
INotifyPropertyChanged
dans tout le modèle commercial.Notre moteur de validation dépend fortement de la notification que les propriétés changent grâce à ce mécanisme et cela fonctionne très bien. Évidemment, si vous utilisez une implémentation différente autre que des objets métier où la notification des modifications n'est pas aussi critique pour l'opération, vous pouvez avoir d'autres méthodes pour détecter les modifications dans votre modèle métier.
Nous avons également des modèles de vue qui propagent les modifications à partir du modèle si nécessaire, mais les modèles de vue eux-mêmes écoutent les modifications de modèle sous-jacentes.
la source
Je suis d'accord avec la réponse de Paulo, la mise
INotifyPropertyChanged
en œuvre dans Models est totalement acceptable et est même suggérée par Microsoft -Bien que ce soit à vous de décider si vous voulez ou non ce type d'implémentation, mais rappelez-vous -
Tiré de - http://msdn.microsoft.com/en-us/library/gg405484(PandP.40).aspx
J'ai travaillé dans certains projets que nous n'avons pas mis
INotifyPropertyChanged
en œuvre dans nos modèles et à cause de cela, nous avons été confrontés à de nombreux problèmes; une duplication inutile des propriétés était nécessaire dans VM et en même temps, nous devions mettre à jour l'objet sous-jacent (avec des valeurs mises à jour) avant de les transmettre à BL / DL.Vous rencontrerez des problèmes spécialement si vous devez travailler avec la collection de vos objets de modèle (par exemple dans une grille ou une liste modifiable) ou des modèles complexes; Les objets de modèle ne seront pas mis à jour automatiquement et vous devrez gérer tout cela dans votre VM.
la source
Mais parfois (comme dans ce texte de lien de présentation ) le modèle est un service, qui fournit à l'application des données en ligne, puis vous devez indiquer que de nouvelles données sont arrivées ou que les données ont changé à l'aide d'événements ...
la source
Je pense que la réponse est assez claire si vous souhaitez adhérer au MV-VM.
voir: http://msdn.microsoft.com/en-us/library/gg405484(v=PandP.40).aspx
Dans le modèle MVVM, la vue encapsule l'interface utilisateur et toute logique d'interface utilisateur, le modèle de vue encapsule la logique et l'état de présentation, et le modèle encapsule la logique métier et les données.
la source
Je dirais dans votre ViewModel. Cela ne fait pas partie du modèle car le modèle est indépendant de l'interface utilisateur. Le modèle devrait être `` tout sauf indépendant des affaires ''
la source
L'implémentation d'INPC dans les modèles peut être utilisée si les modèles sont clairement exposés dans le ViewModel. Mais généralement, le ViewModel encapsule les modèles dans ses propres classes pour réduire la complexité du modèle (ce qui ne devrait pas être utile pour la liaison). Dans ce cas, l'INPC doit être implémenté dans le ViewModel.
la source
J'utilise l'
INotifyPropertyChange
interface dans un modèle. En fait, une modification de propriété de modèle doit être déclenchée par l'interface utilisateur ou le client externe uniquement.J'ai remarqué plusieurs avantages et inconvénients:
Avantages
Notifier fait partie du modèle commercial
Désavantages
Le modèle a des propriétés (quantité, taux, commission, longueur totale). Totalfrieght est calculé en utilisant la quantité, le taux et le changement de commission.
Lors du chargement des valeurs à partir de db, le calcul de la frieght totale est appelé 3 fois (quantité, taux, commission). Ça devrait être une fois.
Si le taux, la quantité est attribué dans la couche de gestion, le notificateur est à nouveau appelé.
Il devrait y avoir une option pour désactiver cela, éventuellement dans la classe de base. Cependant, les développeurs pourraient oublier de le faire.
la source
Je pense que tout dépend du cas d'utilisation.
Lorsque vous avez un modèle simple avec de nombreuses propriétés, vous pouvez le faire implémenter INPC. Par simple je veux dire que ce modèle ressemble plutôt à un POCO .
Si votre modèle est plus complexe et vit dans un domaine de modèle interactif - modèles référençant des modèles, souscription aux événements d'autres modèles - avoir des événements de modèle implémentés comme INPC est un cauchemar.
Mettez-vous dans la position d'une entité modèle qui doit collaborer avec d'autres modèles. Vous avez différents événements auxquels vous inscrire. Tous sont mis en œuvre en tant qu'INPC. Imaginez ces gestionnaires d'événements que vous avez. Une énorme cascade de clauses if et / ou de clausses de commutation.
Un autre problème avec INPC. Vous devez concevoir vos applications pour qu'elles reposent sur l'abstraction et non sur la mise en œuvre. Cela se fait généralement à l'aide d'interfaces.
Jetons un coup d'œil à 2 implémentations différentes de la même abstraction:
Maintenant, regardez les deux. Que vous dit IConnectionManagerINPC? Que certaines de ses propriétés peuvent changer. Vous ne savez pas lequel d'entre eux. En fait, la conception est que seuls les changements IsConnected, car les autres sont en lecture seule.
Au contraire, les intentions d'IConnectionManager sont claires: "Je peux vous dire que la valeur de ma propriété IsConnected peut changer".
la source
Utilisez simplement le
INotifyPropertyChange
dans votre modèle de vue et non dans le modèle,le modèle utilise généralement le
IDataErrorInfo
pour gérer les erreurs de validation, alors gardez simplement votre ViewModel et vous êtes sur la bonne voie pour MVVM.la source
Supposons que la référence de l'objet dans votre vue change. Comment notifierez-vous toutes les propriétés à mettre à jour afin d'afficher les valeurs correctes? Faire appel
OnPropertyChanged
à votre vue pour toutes les propriétés de l'objet est une foutaise à mon point de vue.Donc, ce que je fais est de laisser l'objet lui-même pour avertir quiconque lorsqu'une valeur dans une propriété change, et à mon avis, j'utilise des liaisons comme
Object.Property1
,Object.Property2
et sur. De cette façon, si je veux juste changer l'objet qui est actuellement maintenu dans ma vue, je le fais simplementOnPropertyChanged("Object")
.Pour éviter des centaines de notifications lors du chargement des objets, j'ai un indicateur booléen privé que je le mets à true pendant le chargement qui est vérifié à partir de l'objet
OnPropertyChanged
et ne fait rien.la source
Normalement, ViewModel implémentera le
INotifyPropertyChanged
. Le modèle peut être n'importe quoi (fichier xml, base de données ou même objet). Le modèle est utilisé pour donner les données au modèle de vue, qui se propage à la vue.vois ici
la source
à mon humble avis, je pense que les implémentations viewmodel
INotifyPropertyChange
et le modèle pourraient utiliser la notification à un "niveau" différent.par exemple, avec un service de document et un objet de document, vous avez un événement documentChanged qu'un viewmodel écoute pour effacer et reconstruire la vue. Dans le modèle de vue d'édition, vous avez un changement de propriété pour les propriétés du document afin de prendre en charge les vues. Si le service fait beaucoup avec le document lors de la sauvegarde (mise à jour de la date de modification, dernier utilisateur, etc.), vous obtenez facilement une surcharge d'événements Ipropertychanged et juste un document modifié suffit.
Mais si vous l'utilisez
INotifyPropertyChange
dans votre modèle, je pense que c'est une bonne pratique de le relayer dans votre modèle de vue au lieu de vous y abonner directement dans votre vue. Dans ce cas, lorsque les événements changent dans votre modèle, il vous suffit de changer le modèle de vue et la vue reste intacte.la source
Toutes les propriétés, qui sont liées à ma vue, sont dans mon (mes) ViewModel (s). Ainsi, ils doivent implémenter l'interface INotifyPropertyChanged. Par conséquent, la vue reçoit toutes les modifications.
[En utilisant la boîte à outils MVVM Light, je leur ai laissé hériter de ViewModelBase.]
Le modèle contient la logique métier, mais n'a rien à voir avec la vue. Ainsi, l'interface INotifyPropertyChanged n'est pas nécessaire.
la source