C# 确定在哪个控件上使用了ContextMenuStrip
我有一个C# 确定在哪个控件上使用了ContextMenuStrip,c#,.net,winforms,contextmenustrip,C#,.net,Winforms,Contextmenustrip,我有一个ContextMenuStrip,分配给几个不同的列表框。我正在试图弄清楚什么时候单击了ContextMenuStrip,在什么列表框上使用了它。我尝试了下面的代码作为开始,但它不工作。sender具有正确的值,但当我尝试将其分配给菜单submitted时,该值为空 private void MenuViewDetails_Click(object sender, EventArgs e) { ContextMenu menuSubmitted = sender as Conte
ContextMenuStrip
,分配给几个不同的列表框。我正在试图弄清楚什么时候单击了ContextMenuStrip
,在什么列表框上使用了它。我尝试了下面的代码作为开始,但它不工作。sender
具有正确的值,但当我尝试将其分配给菜单submitted
时,该值为空
private void MenuViewDetails_Click(object sender, EventArgs e)
{
ContextMenu menuSubmitted = sender as ContextMenu;
if (menuSubmitted != null)
{
Control sourceControl = menuSubmitted.SourceControl;
}
}
任何帮助都会很好。谢谢
通过下面的帮助,我找到了答案:
private void MenuViewDetails_Click(object sender, EventArgs e)
{
ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
if (menuItem != null)
{
ContextMenuStrip calendarMenu = menuItem.Owner as ContextMenuStrip;
if (calendarMenu != null)
{
Control controlSelected = calendarMenu.SourceControl;
}
}
}
对于上下文菜单
:
问题是sender
参数指向上下文菜单上单击的项目,而不是上下文菜单本身
不过,这是一个简单的解决方案,因为每个MenuItem
都会公开一个菜单项,告诉您哪个ContextMenu
包含该菜单项
将代码更改为以下内容:
private void MenuViewDetails_Click(object sender, EventArgs e)
{
// Try to cast the sender to a MenuItem
MenuItem menuItem = sender as MenuItem;
if (menuItem != null)
{
// Retrieve the ContextMenu that contains this MenuItem
ContextMenu menu = menuItem.GetContextMenu();
// Get the control that is displaying this context menu
Control sourceControl = menu.SourceControl;
}
}
对于ContextMenuStrip
:
如果您使用ContextMenuStrip
而不是ContextMenu
,它会稍微改变一些事情。这两个控件彼此不相关,不能将一个控件的实例强制转换为另一个控件的实例
与以前一样,单击的项目仍然会在发送者
参数中返回,因此您必须确定拥有此单个菜单项的ContextMenuStrip
。你可以用这个。最后,您将使用确定哪个控件显示上下文菜单
按如下方式修改代码:
private void MenuViewDetails_Click(object sender, EventArgs e)
{
// Try to cast the sender to a ToolStripItem
ToolStripItem menuItem = sender as ToolStripItem;
if (menuItem != null)
{
// Retrieve the ContextMenuStrip that owns this ToolStripItem
ContextMenuStrip owner = menuItem.Owner as ContextMenuStrip;
if (owner != null)
{
// Get the control that is displaying this context menu
Control sourceControl = owner.SourceControl;
}
}
}
较旧的帖子,但万一像我这样的人遇到:
对于一个ContextMenuStrip来说,上面的内容对我来说不起作用,但它让我找到了真正起作用的东西
void DeleteMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
ContextMenuStrip menu = sender as ContextMenuStrip;
Control sourceControl = menu.SourceControl;
MessageBox.Show(sourceControl.Name);
}
这给了我预期控件的名称。您可以使用if语句进行验证等,我只是想说明问题。我很难让这些代码正常工作。这是我能找到的最简单的解决方案:
对于ContextMenuStrip:
最简单的解决办法是:
Control parentControl = ((sender as MenuItem).GetContextMenu()).SourceControl;
将发送者强制转换为ToolStripItem以到达所有者,该所有者将是不具有SourceControl属性的ToolStrip
将所有者强制转换为ContextMenuStrip以访问SourceControl
Control sc = ((ContextMenuStrip)((ToolStripItem)sender).Owner).SourceControl;
在本例中,使用C1网格中的ActiveForm.ActiveControl如何:
C1.Win.FlexGrid.C1FlexGrid fg = frmMain.ActiveForm.ActiveControl as C1.Win.FlexGrid.C1FlexGrid;
@蓝脚:那么你又出了什么问题。我刚刚用三个不同的列表框测试了这段代码,一切都按预期进行了。发布更多的复制代码。@bluefeet:我已经在我的答案中更新了代码。ContextMenu
和ContextMenuStrip
之间有很大区别。(啊,我看你已经弄明白了。好吧,最好是自己学习!)我使用打开事件来记录将菜单打开到局部变量的SourceControl,然后在处理项目单击时引用它。@QuickDanger是的,SourceControl
在触发ContextMenuStrip
的ToolStripItem
子项的Click
事件时不幸为空。似乎ContextMenuStrip
的Closed
事件在单击事件之前触发,这可能是导致问题的原因;我假设该属性在菜单“关闭”后被清除。@CodyGray实际上,如果树更深,则必须循环OwnerItem
属性链,直到找到ToolStripItem
的ContextMenuStrip
属性。但正如我刚才评论的,它不起作用;上下文菜单上的SourceControl
将为空。但是你说你不能复制它。。。也许问题只发生在菜单深度超过一个级别时?我的是两个子层深。谢谢你的解决方案,我一直在寻找。我也有同样的问题。但是我建议不要嵌套所有那些if
语句并使用if(menuItem==null)返回代码>如果你和我一样,不希望处理它的代码嵌套在额外的不必要的两个级别。在我看来,你提供的解决方案可以更简洁地编码:controlcontrolselected=((发送者作为ToolStripMenuItem)?.Owner作为ContextMenuStrip)?.SourceControl代码>这仅适用于上下文菜单中的直接项。问题是单击子菜单项时,ItemClicked
不会触发;他们需要自己的点击事件,该事件将项目本身作为发件人,而不是菜单。我认为此代码更简单,谢谢
C1.Win.FlexGrid.C1FlexGrid fg = frmMain.ActiveForm.ActiveControl as C1.Win.FlexGrid.C1FlexGrid;