如何引用WPF上下文菜单右键点击的对象单击事件处理程序? [英] How to reference right-clicked object in WPF Context Menu item click event handler?
问题描述
在WPF应用程序有一个电网
与多个对象(它们是从一个自定义控件派生)。我想在他们每个人的使用右键菜单中执行某些操作:
In WPF application there is a Grid
with a number of objects (they are derived from a custom control). I want to perform some actions on each of them using context menu:
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Name="EditStatusCm" Header="Change status" Click="EditStatusCm_Click"/>
</ContextMenu>
</Grid.ContextMenu>
不过,在事件处理程序我不能知道哪些对象是右键单击:
But in the event handler I cannot get know which of the objects was right-clicked:
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;
}
在该注释行调试器说:的未将对象引用设置到对象的实例。的
On that commented line Debugger says: Object reference not set to an instance of an object.
请帮忙,什么是错在我的代码?
Please help, what is wrong in my code?
编辑(添加):
我试图做同样的,使用的命令办法
I tried to do the same, using Command approach:
我声明了一个 DataCommands
类具有 RoutedUICommand重新查询
然后用 Window.CommandBindings
I declared a DataCommands
Class with RoutedUICommand Requery
and then used Window.CommandBindings
<Window.CommandBindings>
<CommandBinding Command="MyNamespace:DataCommands.Requery" Executed="RequeryCommand_Executed"></CommandBinding>
</Window.CommandBindings>
菜单项的XAML现在看起来像:
XAML of MenuItem now looks like:
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Name="EditStatusCm" Header="Change status" Command="MyNamespace:DataCommands.Requery"/>
</ContextMenu>
</Grid.ContextMenu>
和事件处理程序是这样的:
And event handler looks like:
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);
}
但调试器显示相同的运行时错误: 对象引用未设置到对象的实例。的
But debugger shows the same run-time error: Object reference not set to an instance of an object.
什么在我的这两种方法丢失?
What is missing in my both approaches?
我应该如何引用WPF上下文菜单项Click事件处理程序右键点击的对象?
How I should reference right-clicked object in WPF Context Menu item click event handler?
推荐答案
请注意在CommandParameter
note the CommandParameter
<Grid Background="Red" Height="100" Width="100">
<Grid.ContextMenu>
<ContextMenu>
<MenuItem
Header="Change status"
Click="EditStatusCm_Click"
CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Parent}" />
</ContextMenu>
</Grid.ContextMenu>
</Grid>
和在处理程序使用它来找出哪些网格是
and use it in the handler to figure out which Grid it is
private void EditStatusCm_Click(object sender, RoutedEventArgs e)
{
MenuItem mi = sender as MenuItem;
if (mi != null)
{
ContextMenu cm = mi.CommandParameter as ContextMenu;
if (cm != null)
{
Grid g = cm.PlacementTarget as Grid;
if (g != null)
{
Console.WriteLine(g.Background); // Will print red
}
}
}
}
更新:的结果
如果你想在菜单项处理程序来获取到网格的孩子而网格本身,使用这种方法。
Update:
If you want the menuitem handler to get to the Grid's children instead of the Grid itself, use this approach
<Grid Background="Red" Height="100" Width="100">
<Grid.Resources>
<ContextMenu x:Key="TextBlockContextMenu">
<MenuItem
Header="Change status"
Click="EditStatusCm_Click"
CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Parent}" />
</ContextMenu>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="ContextMenu" Value="{StaticResource TextBlockContextMenu}" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Row0" Grid.Row="0" />
<TextBlock Text="Row1" Grid.Row="1" />
</Grid>
只需要用无论您的自定义对象类型是的TextBlocks。然后在事件处理程序,替换电网G = cm.PlacementTarget为网格
与 TextBlock的T = cm.PlacementTarget作为TextBlock的
(或任何你自定义的对象类型)。
Just replace the TextBlocks with whatever your custom object type is. Then in the event handler, replace Grid g = cm.PlacementTarget as Grid
with TextBlock t = cm.PlacementTarget as TextBlock
(or whatever your custom object type is).
这篇关于如何引用WPF上下文菜单右键点击的对象单击事件处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!