Comment référencer faites un clic droit sur l'objet dans WPF l'élément de Menu Contextuel cliquez sur gestionnaire d'événement?
En application WPF il y a un Grid
avec un certain nombre d'objets (ils sont dérivés à partir d'un contrôle personnalisé). Je veux effectuer certaines actions sur chacun d'entre eux à l'aide du menu contextuel:
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Name="EditStatusCm" Header="Change status" Click="EditStatusCm_Click"/>
</ContextMenu>
</Grid.ContextMenu>
Mais dans le gestionnaire d'événement je n'arrive pas à savoir lequel de ces objets a été cliqué avec le bouton droit:
private void EditStatusCm_Click(object sender, RoutedEventArgs e)
{
MyCustControl SCurrent = new MyCustControl();
MenuItem menu = sender as MenuItem;
SCurrent = menu.DataContext as MyCustControl; //here I get a run-time error
SCurrent.Status = MyCustControl.Status.Sixth;
}
Sur cette ligne de commentaire Débogueur dit: Objet de référence non définie à une instance d'un objet.
Aider s'il vous plaît, quel est le problème dans mon code?
Modifié (ajout):
J'ai essayé de faire de même, à l'aide de Commande approche:
J'ai déclaré un DataCommands
Classe avec RoutedUICommand Requery
et ensuite utilisé Window.CommandBindings
<Window.CommandBindings>
<CommandBinding Command="MyNamespace:DataCommands.Requery" Executed="RequeryCommand_Executed"></CommandBinding>
</Window.CommandBindings>
XAML de MenuItem ressemble maintenant à:
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Name="EditStatusCm" Header="Change status" Command="MyNamespace:DataCommands.Requery"/>
</ContextMenu>
</Grid.ContextMenu>
Et gestionnaire d'événement ressemble:
private void RequeryCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
IInputElement parent = (IInputElement)LogicalTreeHelper.GetParent((DependencyObject)sender);
MyCustControl SCurrent = new MyCustControl();
SCurrent = (MuCustControl)parent;
string str = SCurrent.Name.ToString();//here I get the same error
MessageBox.Show(str);
}
Mais débogueur affiche la même erreur d'exécution: Objet de référence non définie à une instance d'un objet.
Ce qui est manquant dans mon les deux approches?
Comment je doit faire référence à droite-objet cliqué dans WPF l'élément de Menu Contextuel cliquez sur gestionnaire d'événement?
- J'ai essayé d'utiliser la Commande approche plus WPF-ish, mais j'ai reçu le même message d'erreur. J'ai édité ma question et a ajouté étapes de ma Commande tentative d'approche. Ma compréhension de la façon d'obtenir l'objet cliqué référence manque quelque chose dans les deux cas
Vous devez vous connecter pour publier un commentaire.
note le CommandParameter
et de l'utiliser dans le gestionnaire de figure qui Grille, il est
mise à Jour:
Si vous voulez le menuitem gestionnaire d'obtenir à la Grille des enfants au lieu de la Grille elle-même, l'utilisation de cette approche
Il suffit de remplacer le TextBlocks avec personnalisé quel que soit votre type d'objet est. Ensuite, dans le gestionnaire d'événements, remplacer
Grid g = cm.PlacementTarget as Grid
avecTextBlock t = cm.PlacementTarget as TextBlock
(ou quel que soit votre objet personnalisé est de type).CommandParameter
de liaison n'est pas nécessaire ici, care.Source
peut être utilisé à la place. La seule condition essentielle pour que cela fonctionne est que chaque élément a son propreContextMenu
. Bien queCommandParameter
est significativement moins efficace que l'utilisation dee.Source
en raison des liaisons, vous pouvez facilement faire valoir que c'est plus élégant et par conséquent la valeur de la faible efficacité.En liant les Données de Contexte comme dans le code xaml:
Vous pouvez alors faire ceci:
Le contexte de données sera lié à l'objet qui a été cliqué pour ouvrir le ContextMenu.
Je l'ai eu à partir d'un codeproject l'article sur ce lien:
http://www.codeproject.com/Articles/162784/WPF-ContextMenu-Strikes-Again-DataContext-Not-Upda
menu = sender as MenuItem
sera nulle si l'expéditeur n'est pas un MenuItem ou d'une classe dérivée de celle-ci. Par la suite essayer de déréférencer menu va exploser.Il est probable que votre expéditeur est un Menu ou ContextMenu ou un ToolStripMenuItem ou l'autre forme de l'élément de menu, plutôt que spécifiquement être un objet MenuItem. Utiliser un débogueur point d'arrêt pour stopper le code ici et d'examiner l'objet expéditeur pour voir exactement à quelle classe il est.
Pour RoutedEventArgs
Donc .L'expéditeur doit être la réponse. Mais cela dépend de la façon dont les menuitems sont ajoutés et lié
Voir ce réponse de la collection et choisir la méthode qui va travailler pour vous de la situation!
Ne devriez-vous pas être la vérification de
RoutedEventArgs.Source
au lieu desender
?Vous avez eu deux problèmes différents. Les deux problèmes ont abouti à la même exception, mais n'avaient aucun lien avec:
Premier problème
Dans votre première approche de votre code est correct et a couru bien, sauf pour le problème ici:
Le nom de "Statut" est utilisé à la fois comme un membre statique et en tant que membre de l'instance. Je pense que vous avez coupé et collé le code correctement dans votre question.
Il peut également être nécessaire d'ajouter ce qui suit après
MenuItem menu = sender as MenuItem;
, en fonction de votre situation exacte:Deuxième problème
Dans votre deuxième approche que vous avez utilisé "expéditeur" au lieu de "e.Source". Le code suivant fonctionne comme vous le souhaitez:
Note Finale
Remarque: Il n'y a aucune raison de lier
CommandParameter
pour cela, si vous utilisez le commandant de la démarche. Il est beaucoup plus lente et prend plus de code.e.Source
sera toujours l'objet source, donc il n'est pas nécessaire d'utiliserCommandParameter
, afin de l'utiliser à la place.Cela fonctionne pour moi:-
XAML:-
Pour ajouter des éléments de menu:-
Et ici vient de l'auditeur:-
Merci...
Dans mon cas, j'ai pu utiliser: