8
votes

WPF: mvvm dit non aux convertisseurs mais j'ai besoin de belles valeurs d'énum

Dans le niveau modèle, j'ai défini un énorme:

<UserControl.Resources>

  <ObjectDataProvider 
      x:Key="memberStatusesDataProvider" 
      ObjectType="{x:Type system:Enum}" 
      MethodName="GetValues">
    <ObjectDataProvider.MethodParameters>
      <x:Type TypeName="model:MemberStatus" />
    </ObjectDataProvider.MethodParameters>
  </ObjectDataProvider>

</UserControl.Resources>
...
<ComboBox 
    ItemsSource="{Binding Source={StaticResource memberStatusesDataProvider}}" 
    SelectedItem="{Binding Path=Status}" />
...
  • Boîte combo Choix:
    • Membre actif Li>
    • Membre inactif Li>
    • Associé Li>
    • Membre du tableau LI>
    • Alumni Li> ul> li> ul>

      Également, si la langue de l'application change, j'ai besoin des valeurs ENUM dans cette langue. Pour résoudre ce problème, la première chose qui me suis venu à l'esprit est de créer un convertisseur pour mectatus code> énum. J'ai trouvé cet article puatoire sur le sujet: http://www.codeproject.com/kb/ WPF / FriendCyNeumums.aspx Mais MVVM Modèle dit qu'il ne devrait pas y avoir besoin de les créer presque du tout - et je suis d'accord avec cela. Cependant, cette affirmation ne fonctionne pas en ma faveur dans cet exemple. P>

      Comment est-il censé être fait? Merci. p> p>


4 commentaires

Où avez-vous lu que MVVM ne nécessite aucun convertisseur?


Je regarderais un changement de conception plutôt que de peaufler des convertisseurs. Une bonne solution serait de créer deux classes - mectatus et DisparateMemberstatus . DisparypableMemberstatus ÉTENDURE LISTE ET INITIALISISE SUR LE CONSTRUCTEUR. Éventuellement implémenter comme un singleton.


@nlawalker: Je l'ai trouvé dans le blog de Josh Smith et plusieurs autres sources. Il est en fait souvent mentionné dans les discussions MVVM. Personnellement, je suis d'accord avec cette déclaration, car le but du modèle d'affichage est de traduire le modèle en vue - cela pourrait la préparer à la vue en cours de route.


Je serais en désaccord avec la déclaration à propos de ne pas utiliser de convertisseurs dans MVVM. WPF utilise une utilisation intensive de convertisseurs intégrés et je les utilise régulièrement dans ma programmation MVVM. Je n'ai eu aucun problème avec eux. Je prends des déclarations de couverture comme "mais MVVM modèle dit qu'il ne devrait pas y avoir besoin de les créer" avec un grain de sel. C'est simplement l'opinion d'une personne et une personne avec laquelle de nombreuses personnes sont en désaccord.


4 Réponses :


3
votes

La vue sur laquelle MVVM fait des convertisseurs de valeur obsolètes semble être venu de Josh Smith qui dit dans son blog post Les philosophies de MVVM :

... une classe de menuLoDel est essentiellement un Convertisseur de valeur sur les stéroïdes, ainsi Rendu à l'tivaloConverter interface non pertinente pour la plupart liaisons.

Ce que je prends de cela (et je suis d'accord avec lui pour ce que cela vaut la valeur) est le modèle de vue est responsable de toute conversion de la vue du modèle du monde sur les vues, rendant le convertisseur obsolète.

Avoir une énumération (qui est un type de données de centré de données très de données) dans le modèle exposé à l'interface utilisateur est définitivement une odeur - si seulement pour la raison pour laquelle vous voyez, de montrer moins que des informations idéales à l'utilisateur.

Mettez un mappage de Enum à UI String dans votre modèle de vue.


6 commentaires

Bien que, si le code est plus simple et plus lisible, passez à l'approche du convertisseur de valeur! Mais le "convertisseur sur les stéroïdes" est toujours dans la plupart des cas.


La clé Il y a "la plupart des" liants. Il pourrait y avoir un cas ou deux ou deux où il est préférable d'avoir un convertisseur.


@David: Merci pour la réponse. J'ai un problème de cartographie dans ma situation qui est expliquée ici Stackoverflow.com/Questtions/5706500/... . Donc, fondamentalement, si je m'applique sur des modèles de données et que vous utilisez des classes de modèle pour leurs types de données, je ne peut pas utiliser la propriété mappée définie dans le modèle de vue, car ce n'est pas le contexte de données du modèle. Si je devais utiliser Afficher les propriétés du modèle, la solution fournie pour la question liée n'a pas de sens. Je suis dans deux esprits ici :) S'il vous plaît conseiller, merci.


@Boris J'ai examiné cette question et convient avec le commentateur qui a mentionné avoir plusieurs modèles de données pour un seul VM. Je n'ai pas travaillé sérieusement dans WPF pendant un moment, mais souvenez-vous de faire cela. Ce que je peux dire, c'est que si vous êtes (comme je le pense), contraignant directement à votre modèle, cela détruit l'avantage de MVVM. De plus, vous devez idéalement avoir 1 VM par vue, qui gère toute la traduction de divers éléments de modèle. J'ai parfois une machine virtuelle qui sert un contrôle de l'utilisateur dans une vue, mais c'est lorsque le contrôle de l'utilisateur est essentiellement un composant isolé. Désolé je ne peux pas offrir de code concret en ce moment


@David c'est exactement ce que je pensais! La liaison directe au modèle n'a aucun sens, MVVM sage. En outre, je suis d'accord avec le concept d'avoir 1 modèle de vue par vue, mais aussi avec celui d'avoir 1 modèle d'affichage par composant isolé. Donc, pour mettre fin à cela, une dernière question: comment vous sentez-vous avec l'idée d'avoir beaucoup de propriétés dans le modèle et de mapper chacune d'elles dans le modèle de vue, afin d'éviter une liaison directe? Je demande parce que dans de nombreux cas, il s'avère que le mappage est direct, 1 à 1, ce qui le rend redondant (et le but du modèle est de réduire la redondance).


@Boris qui est éventuellement la plainte numéro un concernant le motif et celui que je n'ai pas encore résolu complètement dans ma propre tête. Je pense que cela dépend vraiment. Si votre modèle est riche, avec beaucoup de logique, l'isolement est bon à son égard, plus il conserve toutes les préoccupations du modèle, si le modèle est juste un DTC, le motif commence à devenir excédent. Un outil pour aider à cela est le modèle de projection de modèle.



2
votes

MVVM n'est pas vraiment placé en pierre quant à quelles parties de WPF sont et ne sont pas autorisées. Les convertisseurs conviennent parfaitement s'ils accomplissent facilement votre objectif. Je suggérerais même de prendre une étape plus loin et de faire un markupextension pour fournir les valeurs ENUM et leurs équivalents de chaîne. Vous pouvez stocker les chaînes dans un descriptionAttribute sur chaque valeur Enum.


3 commentaires

C'est donc des convertisseurs à la fin de votre perspective, non? Si je comprenais correctement, je ferais la valeur Enum à la cartographie de la chaîne là-bas. En outre, une chose de plus, je pense que DescriptionAttribute n'est pas une bonne idée, car de cette façon, les valeurs sont codées dur. Si je supporte différentes langues dans l'application, alors le DescriptionAttribute devrait changer de manière dynamique. Merci d'avoir fourni votre réponse, acclamations.


Vous pouvez fournir une collection source qui était au courant de la langue. L'extension de balisage que j'utilise dans notre produit au travail prend en charge la lecture d'un fichier de ressources pour récupérer les descriptions.


@ user7116 qui est horrible et paresseux. Évitez d'éviter d'éviter. Les fichiers RESX y parviennent déjà. Les outils de localisation existants ne remplacent pas les tableaux de chaînes dans les attributs.



2
votes

Je ne suis pas d'accord que MVVM fait des évaluateurs obsolètes. Il y a plus que suffisamment de scénarios où la mise en oeuvre d'une valeur de valeur constitue plus de sens pour mettre en œuvre la conversion dans la classe ViewModel.

Vous pourriez être intéressé par l'application échantillon d'échantillon de Cadre d'application WPF (WAF ) . Cela montre comment une énumération peut être localisée dans une application MVVM. Veuillez consulter la catégorie Booklibrary.Presentation / Convertisseurs / LanguageTostringConverterConverterConverter.


0 commentaires

3
votes

convertisseurs sont utiles pour aller plus loin que la conversion Enum s. Les convertisseurs sont également plus réutilisables qu'un one-off de ViewModel est.

  • Je voudrais peut-être convertir un bool à un brosse et je peux spécifier les paramètres tous dans la vue.

  • ou peut-être que je veux convertir une chaîne (code> sur DateTime et versez à nouveau tous via une liaison de données. Peut-être que je veux tout convertir en majuscule . Ensuite, il y a mon BooltOvisibilitéConverter .

    Je détesterais mettre explicite directe indirecte tout au long de mon vm s juste pour garder des groupes minoritaires heureux. La chose que je dirais qu'ils oublieraient, c'est que convertisseurs sont facilement accessibles depuis l'expression mélangé .

    Les convertisseurs sont une partie essentielle de la liaison WPF et du supplément entre View et ViewModel .

    Je ne vois aucune raison pour que vous ne puissiez pas les utiliser pour Enum s.


0 commentaires