在 WPF 应用程序中,有一个包含许多对象的 Grid
(它们源自自定义控件)。我想使用上下文菜单对它们中的每一个执行一些操作:
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Name="EditStatusCm" Header="Change status" Click="EditStatusCm_Click"/>
</ContextMenu>
</Grid.ContextMenu>
但是在事件处理程序中我无法知道右键单击了哪个对象:
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;
}
在该注释行上,调试器显示:未将对象引用设置为对象的实例。
请帮忙,我的代码有什么问题?
编辑(添加):
我尝试使用命令方法执行相同的操作:
我使用 RoatedUICommand Requery
声明了一个 DataCommands
类,然后使用 Window.CommandBindings
<Window.CommandBindings>
<CommandBinding Command="MyNamespace:DataCommands.Requery" Executed="RequeryCommand_Executed"></CommandBinding>
</Window.CommandBindings>
MenuItem 的 XAML 现在看起来像:
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Name="EditStatusCm" Header="Change status" Command="MyNamespace:DataCommands.Requery"/>
</ContextMenu>
</Grid.ContextMenu>
事件处理程序如下所示:
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);
}
但调试器显示相同的运行时错误:未将对象引用设置为对象的实例。
我的两种方法都缺少什么?
我应该如何在 WPF 上下文菜单项单击事件处理程序中引用右键单击对象?
最佳答案
注意命令参数
<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>
并在处理程序中使用它来确定它是哪个网格
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
}
}
}
}
更新:
如果您希望菜单项处理程序访问网格的子级而不是网格本身,请使用此方法
<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>
只需将 TextBlock 替换为您的自定义对象类型即可。然后在事件处理程序中,替换 Grid g = cm.PlacementTarget as Grid
与 TextBlock t = cm.PlacementTarget as TextBlock
(或任何您的自定义对象类型)。
关于c# - 如何在 WPF 上下文菜单项单击事件处理程序中引用右键单击对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2032832/