Comment lier les commandes WPF entre un UserControl et une fenêtre parente
Je suis commencer par laisser une image de certains de parler.
Donc, vous voyez, je veux créer un contrôle utilisateur WPF qui prend en charge la liaison à un parent de la fenêtre DataContext. Le contrôle de l'utilisateur est tout simplement un Bouton et une zone de liste avec un ItemTemplate de présenter les choses avec une Étiquette et un Bouton Supprimer.
Le bouton Ajouter devriez appeler un ICommand sur la vue principale de modèle pour interagir avec l'utilisateur dans la sélection d'un nouvel objet (instance de IThing). Le bouton Supprimer dans la ListBoxItem dans le contrôle de l'utilisateur devrait de même appeler un ICommand sur la vue principale de modèle à la demande de la chose de l'enlèvement. Pour que cela fonctionne, le bouton Supprimer aurait pour envoyer des informations d'identification du modèle de vue sur la chose demandé à être retiré. Il y a donc 2 types de Commande qui devrait être pouvant être liées à ce contrôle. Quelque chose comme AddThingCommand() et RemoveThingCommand(IThing chose).
J'ai eu la fonctionnalité de travail à l'aide Cliquez sur les événements, mais qui se sent hacky, la production d'un tas de code derrière le XAML, et se frotte contre le reste de la vierge du MVVM mise en œuvre. J'ai vraiment envie d'utiliser les Commandes et MVVM normalement.
Il y a assez de code pour obtenir une base de démonstration de travail, je suis pas sur de poster le tout afin de réduire la confusion. Quel est le travail qui me fait me sentir comme je suis si près, c'est le DataTemplate pour la ListBox lie l'Étiquette correctement, et lorsque la fenêtre parent ajoute des éléments à la collection, ils affichent.
<Label Content="{Binding Path=DisplayName}" />
Alors que qui affiche la IThing correctement, le bouton Supprimer juste à côté, il ne fait rien quand je clique dessus.
<Button Command="{Binding Path=RemoveItemCommand, RelativeSource={RelativeSource AncestorType={x:Type userControlCommands:ItemManager }}}">
Ce n'est pas très inattendu, car l'élément n'est pas fournie, mais le bouton Ajouter n'est pas nécessaire de spécifier quoi que ce soit, et c'est aussi ne pas appeler la commande.
<Button Command="{Binding Path=AddItemCommand, RelativeSource={RelativeSource AncestorType={x:Type userControlCommands:ItemManager }}}">
Donc ce que j'ai besoin est la "base" pour fixer le bouton Ajouter, afin qu'il appelle le parent de la fenêtre de commande pour ajouter une chose, et la plus complexe à résoudre pour le bouton Supprimer, de sorte qu'il appelle aussi le parent de commande, mais également de passer le long de son lié chose.
Un grand merci pour toutes les suggestions,
source d'informationauteur Todd Sprang
Vous devez vous connecter pour publier un commentaire.
C'est trivial, et par le traitement de votre UserControl pour ce qu'elle est-un contrôle (qui se trouve être composé à partir d'autres contrôles). Qu'est-ce que cela signifie? Cela signifie que vous devez placer DependencyProperties sur votre UC, pour qui votre ViewModel peut se lier, comme n'importe quel autre contrôle. Boutons exposer une Commande de la propriété, les zones de texte exposer une propriété de Texte, etc. Vous avez besoin d'exposer, sur la surface de votre UserControl, tout ce dont vous avez besoin pour faire son travail.
Prenons un trivial (jetés ensemble en moins de deux minutes) exemple. Je vais laisser la ICommand mise en œuvre.
Tout d'abord, notre Fenêtre
Avis, nous avons nos Articles éditeur, qui expose les propriétés pour tout ce qu'il faut--la liste des éléments qu'il est de l'édition, une commande pour ajouter un nouvel élément, et une commande pour supprimer un élément.
Prochain, le contrôle UserControl
Nous lient nos contrôles pour le DPs définie sur la surface de l'UC. S'il vous plaît, ne faites pas de bêtises comme
DataContext=this;
que cet anti-modèle se casse plus complexes, les solutions de communications UNIFIÉES.Voici les définitions de ces propriétés sur l'UC
DPs juste sur la surface de l'UC. Pas trop grave. Et notre ViewModel est aussi simple
Vous modifiez trois collections différentes, de sorte que vous pouvez exposer plus ICommands de préciser qui vous êtes ajout/suppression. Ou vous pourriez pas cher et de l'utilisation de la CommandParameter figure.
Consulter le code ci-dessous.
UserControl.XAML
Fenêtre.Xaml
Fenêtre.xaml.cs
ThingViewModel.cs
Chose.cs
BaseCommand.cs
Au lieu de la Base de commande, vous pouvez essayer RelayCommand de MVVMLight ou DelegateCommand à partir du PRISME des bibliothèques.
Par défaut, votre compte utilisateur sera hériter du DataContext de son conteneur. De sorte que le ViewModel de la classe de votre fenêtre utilise peut être lié directement par le contrôle de l'utilisateur, à l'aide de la Liaison de la notation dans le XAML. Il n'y a pas besoin de spécifier DependentProperties ou RoutedEvents, juste lier les propriétés de la commande comme d'habitude.