MVVM Acheminés et Relais de Commande
Quelle est la Différence entre le RoutedCommand et RelayCommand ?
Quand utiliser RoutedCommand et quand utiliser RelayCommand dans le pattern MVVM ?
Vous devez vous connecter pour publier un commentaire.
Quelle est la Différence entre le RoutedCommand et RelayCommand ?
Quand utiliser RoutedCommand et quand utiliser RelayCommand dans le pattern MVVM ?
Vous devez vous connecter pour publier un commentaire.
RoutedCommand est partie de WPF, alors que RelayCommand a été créé par un WPF Disciple, Josh Smith ;).
Sérieusement, si, RS Conley a décrit certaines des différences. La principale différence est que RoutedCommand est un ICommand de mise en œuvre qui utilise un RoutedEvent à la route à travers les arbres jusqu'à ce qu'un CommandBinding pour la commande se trouve, alors que RelayCommand ne fait pas de routage et au lieu directement exécute un délégué. Dans un M-V-VM scénario un RelayCommand (DelegateCommand dans Prism) est probablement le meilleur choix tout autour.
Concernant l'utilisation de RelayCommand et RoutedCommand dans MVVM la principale différence pour moi est la suivante:
Emplacement du code
RelayCommand permet de mettre en oeuvre la commande dans n'importe quelle classe (ICommand-propriété avec des délégués), qui est ensuite classiquement lié aux données pour le contrôle, qui appelle la commande. Cette classe est la ViewModel.
Si vous utilisez une commande routée, vous aurez à mettre en œuvre les méthodes liées à la commande dans le codebehind du contrôle, parce que les méthodes sont spécifiées par les attributs de la CommandBinding-élément. Supposé que le strict MVVM signifie avoir un "vide" codebehind-fichier, il n'existe pas de possibilité d'utiliser la norme acheminé commandes avec MVVM.
Ce que RS Conley a dit, que RelayCommand vous permet de définir la RelayCommand à l'extérieur de ce Dernier est de droite, mais tout d'abord il vous permet de définir à l'intérieur de le ViewModel, qui RoutedCommand ne le fait pas.
De routage
D'autre part, RelayCommands ne prennent pas en charge le routage grâce à l'arbre (comme dit précédemment), ce qui n'est pas un problème, tant que votre interface est basée sur un seul viewModel. Si elle n'est pas, par exemple, si vous avez une collection d'éléments avec leur propre viewmodel et souhaitez invoquer une commande de l'enfant ViewModel pour chaque élément de l'élément parent à la fois, vous devrez utiliser le routage (voir aussi CompositeCommands).
Dans l'ensemble, je dirais que la norme RoutedCommands ne sont pas utilisables dans le strict MVVM. RelayCommands sont parfaits pour MVVM mais ne prennent pas en charge le routage, qui vous pourriez avoir besoin.
La différence est que RelayCommand peut accepter des délégués. Vous pouvez définir la RelayCommand à l'extérieur de ce Dernier. Le ViewModel peut ensuite ajouter des délégués de la commande lorsqu'il crée et se lie à la commande à un objet d'INTERFACE utilisateur comme un contrôle. Les délégués peuvent à leur tour accès à la variable privée de ce Dernier comme ils sont définis dans la portée de la Vue Modèle lui-même.
Il est utilisé pour réduire la quantité de code contenu dans le ViewModel que la tendance est de définir une commande Routée en tant que classe imbriquée à l'intérieur du ViewModel. Les fonctionnalités des deux est par ailleurs similaire.
Je dirais que RoutedCommands sont parfaitement légales dans le strict MVVM. Bien que RelayCommands sont souvent préférables pour leur simplicité, RoutedCommands offrent parfois des avantages organisationnels. Par exemple, vous pourriez voulez que plusieurs vues différentes pour se connecter à une salle de ICommand instance sans exposer directement à la commande de la sous-Viewmodel.
Comme une note de côté, n'oubliez pas que le strict MVVM n'interdit pas l'utilisation de code-behind. Si cela était vrai, alors vous pourriez ne jamais définir des propriétés de dépendance à votre point de vue!
Afin d'utiliser un RoutedCommand dans un strict MVVM cadre vous pourriez suivre ces étapes:
Déclarer statique RoutedCommand instance pour la réalisation de votre commande. Vous pouvez ignorer cette étape si vous prévoyez d'utiliser une commande prédéfinie de la ApplicationCommands classe. Par exemple:
Joindre souhaité en vue du RoutedCommand en utilisant XAML:
L'un de vos points de vue, qui est lié à une ViewModel (c'est à dire selon le ViewModel implémente la fonctionnalité de commande) doit exposer une coutume DependencyProperty qui sera lié à votre ViewModel de la mise en œuvre:
Le même point de vue doit se lier à la RoutedCommand à partir de l'étape 1. Dans le code XAML:
Dans le code-behind de la vue, l'événement associé gestionnaires juste délégué à la ICommand de la propriété de dépendance déclarée à l'étape 3:
Enfin, lier votre ViewModel de la commande de mise en œuvre (ce qui devrait être un ICommand) à la coutume de la propriété de dépendance dans le code XAML:
L'avantage de cette approche est que votre ViewModel ne doit fournir qu'une seule mise en œuvre de l'interface ICommand (et il peut même être un RelayCommand), alors que n'importe quel nombre de Vues pouvez la joindre par l'intermédiaire de l'RoutedCommand sans avoir besoin d'être directement lié à ce Dernier.
Malheureusement, il n'est pas un inconvénient que le ICommand.Événement CanExecuteChanged ne fonctionnera pas. Lorsque votre ViewModel veut le point de Vue d'actualiser la CanExecute propriété, alors vous devez appeler le Gestionnaire de commandes.InvalidateRequerySuggested().