2014-09-15 1 views
1

Pour un nouveau projet, il m'a récemment été demandé d'étudier une méthode de liaison des informations relatives au rendu de l'interface utilisateur aux objets métier dans une application WPF. Par exemple, une classe de rapport:Définition des propriétés de l'interface utilisateur à l'aide des attributs

class ExecutionReport 
{ 
    [Displayable(Bold, Background=Color.Red)] 
    public String OrderId{get; private set;} 

    [Displayable(Normal, HAlignment=Center)] 
    public String Symbol {get; private set;} 

    // this should be hidden as it doesn't have DisplayableAttribute 
    public String ClientOrderId {get; private set;}] 

    [Displayable(Normal, HAlignment=Right, 
     Format("If [Position] < 0 then Background=Color.Red"), 
     Format("If [Position] > 0 then Background=Color.Lime"), 
     DisplayFormat("+#;-#;0")] 
    public Int Position {get; private set;} 
} 

Ceci est une toute nouvelle approche pour moi comme généralement dans la plupart WPF applications MVVM j'ai travaillé là-bas a été une séparation claire de la vue et viewmodel et je cherche autant que possible pour garder les détails spécifiques à l'interface utilisateur hors de la machine virtuelle. Au lieu de cela je pencherais vers l'écriture de ceci en utilisant des dictionnaires de ressources et des convertisseurs simples appliqués sur les liaisons dans la couche de vue. Mes questions sont les suivantes: Y a-t-il des frameworks wpf/mvvm qui utilisent ce type d'implémentation? Si oui, je suis curieux de voir comment cela serait réalisé.

Y a-t-il des pièges évidents? Les premières choses couple qui me viennent à l'esprit sont

  • notification du changement (ie. INotifyPropertyChanged pour déclencher une mise à jour de la vue). Est-ce que la mise en œuvre de cette mesure serait beaucoup plus difficile maintenant?

  • Difficulté à tirer parti des dictionnaires de ressources pour les valeurs à l'échelle du système. Par exemple, peut-être que je voulais changer la couleur du rouge utilisé dans toute l'application. Je dois ctrl + f à travers et trouver tous les lieux dans les objets d'affaires où il a été utilisé et le changer au lieu d'être en mesure de modifier un seul StaticResource

  • Incapacité à tirer parti DesignTime DataContexts

  • Performance. Semble aime cela nécessiterait une utilisation intensive de réflexion qui pourrait ne pas être aussi performant que les convertisseurs de valeur typique

Je suis très curieux de voir si je ne me trompe pas sur les deuxième et troisième points ou si ces deux choses pourrait encore être atteint? En fin de compte, je pense que c'est un mauvais design et je suis penché vers l'écriture d'une implémentation différente pour montrer à la partie intéressée comment j'aborderais ce type de problème. Je veux juste m'assurer que je ne manque pas quelque chose d'évident qui pourrait le rendre plus élégant.

Répondre

1

Cette approche est très populaire et s'appelle la programmation orientée aspect (ASP.NET MVC en tire parti). La bibliothèque la plus populaire pour écrire ceci rapidement est PostSharp (voir les études de cas de clients, il y a quelques compagnies qui l'ont employé pour WPF). La meilleure chose dans PostSharp est qu'il utilise tissage à la compilation.

Pour le premier point: PostSharp obtenu bien testé aspect NotifyPropertyChanged, vous pouvez ajouter [NotifyPropertyChanged] attribut à la classe et toutes les propriétés appellera PropertyChanged lorsque la valeur est changée.Pour le deuxième point: vous pouvez toujours faire en sorte que votre attribut recherche StaticResources et transmettre la clé de ressource dans l'attribut. Pour le troisième (bien que je ne sois pas sûr à 100%) et le quatrième point: le temps de compilation signifie que l'aspect est "ajouté" au code lors de la compilation - comme vous l'auriez écrit dans la méthode/propriété auquel vous avez ajouté un attribut. C'est comme un compilateur post-build et n'utilise pas de réflexion (si l'aspect que vous avez écrit n'utilise pas de réflexion), la performance est vraiment bonne. Cependant, dans l'exemple que vous avez donné, je préfère aller avec des convertisseurs de valeur et des styles comme @AwkwardCoder - mais les aspects (attributs) sont également utiles avec «view» par exemple: ils sont parfaits pour la validation.

+0

est-ce que AOP prend en charge le débogage ou sont-ils tous tissés après la compilation? – AwkwardCoder

+0

@AwkwardCoder semble que vous pouvez le faire: http://doc.postsharp.net/debugging – fex

3

IMO cela semble être une idée horrible, ils semblent tous être des exemples qui devraient être implémentés en tant que convertisseurs XAML.

Tous les points de la liste semblent être des raisons valables pour éviter cela.

Remarque: Il existe un ensemble d'attributs dans le framework qui fournissent déjà certaines fonctionnalités de l'interface utilisateur (très limitées), voir l'espace de noms System.ComponentModel.DataAnnotations.

1

Je suis d'accord que cela semble être une idée horrible, et votre commentaire ...

dans la plupart des applications MVVM WPF Je travaille là-bas a été une séparation claire de la vue et viewmodel et je cherche autant que possible pour garder les détails spécifiques à l'interface utilisateur hors de la machine virtuelle. Au lieu de cela, je pencherais vers écrit cela en utilisant des dictionnaires de ressources et des convertisseurs simples appliqués sur les liaisons dans la couche de vue

... Je pense que résume pourquoi et comment l'éviter.

Lier vos objets métier directement aux détails d'implémentation tels que la couleur, l'alignement horizontal ou la position, semble être une victoire à court terme (mais un enfer à long terme).

+0

'semble être une victoire à court terme (mais l'enfer à long terme).' tellement vrai... – AwkwardCoder

Questions connexes