如何防止在父控件中处理菜单项上的单击?
本文关键字:菜单项 单击 处理 何防止 控件 | 更新日期: 2023-09-27 18:18:57
我有一个NotifyIcon
和一个ContextMenu
。
myNotifyIcon = new NotifyIcon(new Container());
myNotifyIcon.Click += new EventHandler(myNotifyIcon_Click);
MenuItem entQuit = new MenuItem("Menu Item Text");
entQuit.Click += new EventHandler(entQuit_Click);
myNotifyIcon.ContextMenu = new ContextMenu();
myNotifyIcon.ContextMenu.MenuItems.Add(entQuit);
当我点击菜单中的MenuItem
, myNotifyIcon.Click
火灾,导致myNotifyIcon_Click()
运行(这是我不想要的)。我怎样才能防止这种行为呢?
我错了,这个问题的答案不工作。这个答案似乎确实有效,尽管我不知道为什么。我已经看了这个问题的答案,但他们似乎并没有真正解决这个问题。需要明确的是,问题是当我在上下文菜单中左键单击项时,不是用右键单击打开菜单。<标题>编辑
如果可能的话,您应该考虑使用较新的ContextMenuStrip
但是,如果这是不可能的,那么解决方案是通过查看鼠标的位置来确定是否单击了菜单项。这个解决方案使用GetMenuItemRect来确定一个菜单项是否被点击。
例如:using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class Form2 : Form {
NotifyIcon myNotifyIcon = new NotifyIcon() { Icon = SystemIcons.Exclamation };
MenuItem entQuit = new MenuItem("Menu Item Text");
MenuItem entQuit2 = new MenuItem("Menu Item Text2");
List<Rectangle> rectangles = new List<Rectangle>();
public Form2() {
//ContextMenuStrip cms;
myNotifyIcon.Click += myNotifyIcon_Click;
entQuit.Click += entQuit_Click;
var cm = new ContextMenu();
myNotifyIcon.ContextMenu = cm;
myNotifyIcon.ContextMenu.MenuItems.Add(entQuit);
myNotifyIcon.ContextMenu.MenuItems.Add(entQuit2);
myNotifyIcon.Visible = true;
myNotifyIcon.ContextMenu.Popup += delegate {
this.BeginInvoke((Action) delegate {
var h = myNotifyIcon.ContextMenu.Handle;
rectangles = new List<Rectangle>();
for (int i = 0; i < cm.MenuItems.Count; i++) {
RECT cr = new RECT();
GetMenuItemRect(IntPtr.Zero, h, (uint) i, ref cr);
rectangles.Add(new Rectangle(cr.Left, cr.Top, cr.Right - cr.Left, cr.Bottom - cr.Top));
}
});
};
}
void entQuit_Click(object sender, EventArgs e) {
}
void myNotifyIcon_Click(object sender, EventArgs e) {
bool OnMenuItem = false;
var mp = Form.MousePosition;
foreach (var r in rectangles) {
if (r.Contains(mp)) {
OnMenuItem = true;
break;
}
}
// reset rectangles to prevent icon click from scanning previous rectangles
rectangles = new List<Rectangle>();
if (OnMenuItem) { // detect if click was on a menu item
return;
}
}
[DllImport("user32.dll")]
static extern bool GetMenuItemRect(IntPtr hWnd, IntPtr hMenu, uint uItem, ref RECT rect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT {
public int Left;
public int Top;
public int Right;
public int Bottom;
}
}
最后看起来这个答案可能真的有帮助。我能够通过处理NotifyIcon.MouseClick
而不是NotifyIcon.Click
来解决问题,并检查MouseEventArgs.Button
属性
最后,这似乎行得通:
myNotifyIcon = new NotifyIcon(new Container());
myNotifyIcon.MouseClick += new MouseEventHandler(myNotifyIcon_Click);
MenuItem entQuit = new MenuItem("Menu Item Text");
entQuit.Click += new EventHandler(entQuit_Click);
myNotifyIcon.ContextMenu = new ContextMenu();
myNotifyIcon.ContextMenu.MenuItems.Add(entQuit);
myNotifyIcon_Click
看起来像这样:
void myNotifyIcon_Click(object source, MouseEventArgs e)
{
if(e.Button == MouseButtons.Left) //For some reason this is necessary.
{ //Do stuff here }
}
我不能说我理解为什么这解决了问题,或者为什么我需要检查if(e.Button == MouseButtons.Left)
当点击导致整个问题是左键点击,但它确实工作。