gpt4 book ai didi

c# - 右键单击菜单项时如何显示上下文菜单

转载 作者:可可西里 更新时间:2023-11-01 09:06:03 32 4
gpt4 key购买 nike

我正在将 MFC 应用程序移植到 .NET WinForms。在 MFC 应用程序中,您可以右键单击菜单或上下文菜单项,我们会显示另一个包含诊断和配置项的上下文菜单。我正在尝试将此功能移植到 .NET,但遇到了问题。

我已经能够捕获右键单击,禁用底层菜单的单击并在正确位置弹出上下文菜单,但是一旦失去焦点,原始菜单就会消失。

在 MFC 中,我们通过使用 TPM_RECURSE 标志调用 TrackPopupMenuEx 来显示新的上下文菜单。

ContextMenu 和 .NET 中较新的 ContextMenuStrip 类只有一个 Show 方法。有谁知道如何在 .NET 中执行此操作?

编辑

我已经尝试通过 p/invoke 使用 TrackPopupMenuEx,但这限制了您使用 ContextMenu 而不是 ContextMenuStrip,这在我们的应用程序中看起来不合适。它也仍然无法正常工作。它不适用于新的 MenuStripContextMenuStrip

我还尝试了子类化 ToolStripMenuItem 以查看是否可以向其添加上下文菜单。这适用于 MenuStrip,但 ContextMenuStrip 仍然允许右键单击事件作为点击传递。

最佳答案

编辑,由于评论:

在:

protected override void OnClick(EventArgs e)
{
if (SecondaryContextMenu == null || MouseButtons != MouseButtons.Right)
{
base.OnClick(e);
}
}

这部分

 MouseButtons != MouseButtons.Right

应该并且确实会编译,因为它是对 Control.MouseButtons 的调用。由于Form继承了Control类,直接调用MouseButtons属性即可。

希望对您有所帮助:

public partial class Form1 : Form
{
class CustomToolStripMenuItem : ToolStripMenuItem
{
private ContextMenuStrip secondaryContextMenu;

public ContextMenuStrip SecondaryContextMenu
{
get
{
return secondaryContextMenu;
}
set
{
secondaryContextMenu = value;
}
}

public CustomToolStripMenuItem(string text)
: base(text)
{ }

protected override void Dispose(bool disposing)
{
if (disposing)
{
if (secondaryContextMenu != null)
{
secondaryContextMenu.Dispose();
secondaryContextMenu = null;
}
}

base.Dispose(disposing);
}

protected override void OnClick(EventArgs e)
{
if (SecondaryContextMenu == null || MouseButtons != MouseButtons.Right)
{
base.OnClick(e);
}
}
}

class CustomContextMenuStrip : ContextMenuStrip
{
private bool secondaryContextMenuActive = false;
private ContextMenuStrip lastShownSecondaryContextMenu = null;

protected override void Dispose(bool disposing)
{
if (disposing)
{
if (lastShownSecondaryContextMenu != null)
{
lastShownSecondaryContextMenu.Close();
lastShownSecondaryContextMenu = null;
}
}
base.Dispose(disposing);
}

protected override void OnControlAdded(ControlEventArgs e)
{
e.Control.MouseClick += new MouseEventHandler(Control_MouseClick);
base.OnControlAdded(e);
}

protected override void OnControlRemoved(ControlEventArgs e)
{
e.Control.MouseClick -= new MouseEventHandler(Control_MouseClick);
base.OnControlRemoved(e);
}

private void Control_MouseClick(object sender, MouseEventArgs e)
{
ShowSecondaryContextMenu(e);
}

protected override void OnMouseClick(MouseEventArgs e)
{
ShowSecondaryContextMenu(e);
base.OnMouseClick(e);
}

private bool ShowSecondaryContextMenu(MouseEventArgs e)
{
CustomToolStripMenuItem ctsm = this.GetItemAt(e.Location) as CustomToolStripMenuItem;

if (ctsm == null || ctsm.SecondaryContextMenu == null || e.Button != MouseButtons.Right)
{
return false;
}

lastShownSecondaryContextMenu = ctsm.SecondaryContextMenu;
secondaryContextMenuActive = true;
ctsm.SecondaryContextMenu.Closed += new ToolStripDropDownClosedEventHandler(SecondaryContextMenu_Closed);
ctsm.SecondaryContextMenu.Show(Cursor.Position);
return true;
}

void SecondaryContextMenu_Closed(object sender, ToolStripDropDownClosedEventArgs e)
{
((ContextMenuStrip)sender).Closed -= new ToolStripDropDownClosedEventHandler(SecondaryContextMenu_Closed);
lastShownSecondaryContextMenu = null;
secondaryContextMenuActive = false;
Focus();
}

protected override void OnClosing(ToolStripDropDownClosingEventArgs e)
{
if (secondaryContextMenuActive)
{
e.Cancel = true;
}

base.OnClosing(e);
}
}

public Form1()
{
InitializeComponent();


CustomToolStripMenuItem itemPrimary1 = new CustomToolStripMenuItem("item primary 1");
itemPrimary1.SecondaryContextMenu = new ContextMenuStrip();
itemPrimary1.SecondaryContextMenu.Items.AddRange(new ToolStripMenuItem[] {
new ToolStripMenuItem("item primary 1.1"),
new ToolStripMenuItem("item primary 1.2"),
});

CustomToolStripMenuItem itemPrimary2 = new CustomToolStripMenuItem("item primary 2");
itemPrimary2.DropDownItems.Add("item primary 2, sub 1");
itemPrimary2.DropDownItems.Add("item primary 2, sub 2");
itemPrimary2.SecondaryContextMenu = new ContextMenuStrip();
itemPrimary2.SecondaryContextMenu.Items.AddRange(new ToolStripMenuItem[] {
new ToolStripMenuItem("item primary 2.1"),
new ToolStripMenuItem("item primary 2.2"),
});

CustomContextMenuStrip primaryContextMenu = new CustomContextMenuStrip();
primaryContextMenu.Items.AddRange(new ToolStripItem[]{
itemPrimary1,
itemPrimary2
});

this.ContextMenuStrip = primaryContextMenu;
}
}

关于c# - 右键单击菜单项时如何显示上下文菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/281831/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com