MVVM de liaison de commande à contextmenu élément
Je suis en train de lier une commande pour un menuitem en WPF. Je suis en utilisant la même méthode que pour tous mes autres liaisons de commande, mais je ne peux pas comprendre pourquoi ça ne fonctionne pas ici.
Je suis actuellement à la liaison de mes commandes comme ceci:
Command = "{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.MyCommand}"
C'est là que ça se passe mal (ce qui est à l'intérieur d'un UserControl)
<Button Height="40" Margin="0,2,0,0" CommandParameter="{Binding Name}"
Command = "{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.ConnectCommand}">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Remove" CommandParameter="{Binding Name}"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.RemoveCommand}"/>
</ContextMenu>
</Button.ContextMenu>
...
La première liaison de commande fonctionne comme il le devrait, mais le second refuse de faire quoi que ce soit.
J'ai essayé de changer l'ancêtre de niveau et de nommer mon Contrôle d'accès à travers ElementName au lieu de RelativeSource, mais toujours pas de changement. Il continue en disant: "Impossible de trouver la source de la liaison avec la référence..."
Ce qui me manque?
- J'ai dû vérifier, mais la MenuItem peut-être un autre arbre, de sorte qu'il ne peut pas trouver l'objet UserControl puisque, techniquement, ce n'est pas un ancêtre (Snoop pourrait confirmer si je me souviens de ce droit ou non). Pour les autres liaisons de commande (telles que la commande pour le contrôle de Bouton), pourquoi tu ne peux pas faire de Commande="{Binding Path=commande connect}" ? Le Bouton doit être hériter du DataContext de la UserControl et donc nécessitent pas l'ensemble de la RelativeSource/FindAncestor de la syntaxe.
Vous devez vous connecter pour publier un commentaire.
(Edit) Depuis que vous l'avez mentionné, c'est dans un ItemsControl du modèle, les choses sont différentes:
1) Obtenir le BindingProxy classe à partir de ce blog (et de lire le blog, car c'est intéressant de l'information): Comment lier des données lorsque le DataContext est pas héréditaire.
Essentiellement les éléments dans le ItemsControl (ou ContextMenu) ne font pas partie du visuel ou de l'arborescence logique, et, par conséquent, ne peut pas trouver le DataContext de votre UserControl. Mes excuses pour ne pas écrire plus sur ce sujet ici, mais l'auteur a fait un bon travail en expliquant étape par étape, donc il n'y a aucun moyen que je pourrais donner une explication complète en seulement quelques lignes.
2) Faire quelque chose comme ceci: (vous peut-être adapter un peu pour le faire fonctionner dans votre contrôle):
un. Cela vous donnera accès à l'objet UserControl DataContext à l'aide d'un StaticResource:
b. Il utilise la DataContextProxy définie en (a):
Cela a fonctionné pour nous dans des choses comme les arbres et les datagrids.
<ItemsControl ItemsSource="{Binding AllConnections}"/>
C'est pourquoi la manière la plus simple de lier les commandes ne fonctionnent pas parce qu'ils ne sont pas dans ces modèles (je pense, c'est encore surtout de la magie pour moi)ContextMenu est dans des logiques différentes de l'arbre, c'est pourquoi RelativeSource ne marche pas. Mais menu contextuel hériter DataContext de son "contenant", dans ce cas, c'est le Bouton. Il est assez dans cas le plus courant, mais dans votre cas, vous avez besoin de deux de données "contextes", de ItemsControl élément et de ItemsControl lui-même.
Je pense que vous n'avez pas d'autre choix que de combiner les modèles de vue dans un, mettre en œuvre classe personnalisée pour être utilisé comme ItemsControl élément de contexte de données et contiennent à la fois "Nom" et "Supprimer la commande" ou votre point de vue modèle peut définir RemoveCommand "proxy", qui serait d'appeler le parent de commande interne
EDIT:
J'ai légèrement changé de Babouin code, il doit travailler de cette façon:
koshdim est sur place, il fonctionne comme un charme!! Grâce Koshdim
J'ai modifié son code pour l'adapter dans mon menu contextuel
C'est une question délicate, assurez-vous légèrement, vous trouverez une solution de rechange rapide, mais ici, c'est un non-magie-solution:
Il se résume à l'aide de la
Tag
de laPlacementTarget
(leButton
ici).