如何将ContextMenuStrip添加到ToolStripMenuItem

时间:2013-11-15 06:19:40

标签: c# winforms binding contextmenu

我希望当我点击一个菜单项时,显示一个上下文菜单,其中包含“删除”,“重命名”等项目。

右键单击菜单项时如何绑定自身的上下文菜单?

1 个答案:

答案 0 :(得分:2)

我想到的第一个想法就是在MouseDown上挂上一些ToolStripMenuItem事件,并在屏幕坐标中的鼠标位置显示第二个ContextMenuStrip。但事情并非如此简单。问题是这样做将需要连接事件对于每一的项目,该事件在某种程度上显示了第二ContextMenuStrip 将关闭目前的ContextMenuStrip(即使我们增加一些Closing事件处理程序并设置e.Cancel = true;)。这里有点棘手。我们可以想到当前MouseDown的{​​{1}}事件,但实际上这个事件几乎没有被触发,因为所有项目都位于ContextMenuStrip之上。这让我想到了我们可以捕获ContextMenuStrip并在那里运行代码的更深层次的阶段。我们可以自定义WM_RBUTTONDOWN以在ContextMenuStrip中捕获该邮件,或者我们可以使用自定义WndProc。我想在这里使用NativeWindow。这是代码的时间(完美地工作):

NativeWindow

用法::重要事件为public class NativeContextMenuStrip : NativeWindow { public class ShowContextMenuEventArgs : EventArgs { public ToolStripDropDown ContextMenuToShow {get; set;} } public delegate void ShowContextMenuEventHandler(ShowContextMenuEventArgs e); public event ShowContextMenuEventHandler ShowContextMenu; private Color previousItemBackColor; public ToolStripItem SourceItem { get; set; } bool keepOpen; protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == 0x204) {//WM_RBUTTONDOWN OnShowContextMenu(new ShowContextMenuEventArgs()); } } protected virtual void OnShowContextMenu(ShowContextMenuEventArgs e) { var handler = ShowContextMenu; if (handler != null) { handler(e); if (e.ContextMenuToShow != null) { ContextMenuStrip toolStrip = (ContextMenuStrip)Control.FromHandle(Handle); Point client = toolStrip.PointToClient(Control.MousePosition); SourceItem = toolStrip.GetItemAt(client); previousItemBackColor = SourceItem.BackColor; SourceItem.BackColor = SystemColors.MenuHighlight; e.ContextMenuToShow.Closed -= restoreItemState; e.ContextMenuToShow.Closed += restoreItemState; keepOpen = true; e.ContextMenuToShow.Show(Control.MousePosition); keepOpen = false; } } } protected override void OnHandleChange() { base.OnHandleChange(); ContextMenuStrip toolStrip = Control.FromHandle(Handle) as ContextMenuStrip; if (toolStrip != null) { toolStrip.Closing += toolStripClosing; } } private void restoreItemState(object sender, EventArgs e) { SourceItem.BackColor = previousItemBackColor; SourceItem.Owner.Show(); } private void toolStripClosing(object sender, ToolStripDropDownClosingEventArgs e) { e.Cancel = keepOpen; } } ,将此事件挂钩并设置您要显示的ShowContextMenu。就这样。这是详细信息:

ContextMenuStrip

要点击显示子public partial class Form1 : Form { public Form1(){ InitializeComponent(); //suppose you have a main ContextMenuStrip and a sub ContextMenuStrip //try adding some items for both ContextMenuStrip = new ContextMenuStrip(); ContextMenuStrip.Items.Add("Item 1"); ContextMenuStrip.Items.Add("Item 2"); //sub ContextMenuStrip var subMenu = new ContextMenuStrip(); subMenu.Items.Add("Delete"); subMenu.Items.Add("Rename"); ContextMenuStrip.HandleCreated += (s,e) => { nativeMenu.AssignHandle(ContextMenuStrip.Handle); nativeMenu.ShowContextMenu += (ev) => { ev.ContextMenuToShow = subMenu; }; }; } NativeContextMenuStrip nativeMenu = new NativeContextMenuStrip(); } 的项目,您可以访问ContextMenuStrip的{​​{1}}。

enter image description here