从ToolStripMenuItem中打开上下文菜单

本文关键字:上下文 菜单 ToolStripMenuItem | 更新日期: 2023-09-27 18:15:23

我试图模仿Windows资源管理器的行为,以及收藏夹项如何启动上下文菜单。

我当前正在使用:

contextMenu.Show((sender as ToolStripMenuItem).GetCurrentParent().PointToScreen(e.Location));

这发生在ToolStripMenuItem的MouseDown事件中。问题是菜单在右键单击后立即关闭,我不知道在上下文菜单打开时暂停它的任何方法。

我试过从ToolStripMenuItem派生并重写MouseDown/MouseUp,但我不知道如何在单击时保持打开。

是否有好的方法来做到这一点?

从ToolStripMenuItem中打开上下文菜单

这是我的运气,它更直接一点:

    public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    void MenuItemContext(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left) return;
        ToolStripMenuItem mID = (ToolStripMenuItem)sender;
        ContextMenu tsmiContext = new ContextMenu();
        MenuItem Item1 = new MenuItem();
        MenuItem Item2 = new MenuItem();
        Item1.Text = "Item1";
        Item2.Text = "Item2";
        tsmiContext.MenuItems.Add(Item1);
        tsmiContext.MenuItems.Add(Item2);
        Item1.Click += new EventHandler(Item1_Click);
        Item2.Click += new EventHandler(Item2_Click);
        hndPass = mID.Text;
        tsmiContext.Show(menuStrip1, menuStrip1.PointToClient(new Point(Cursor.Position.X, Cursor.Position.Y)));
    }
    private String hndPass;
    void Item1_Click(object sender, EventArgs e)
    {
       MenuItem mID = (MenuItem)sender;
        MessageBox.Show("You clicked " + mID.Text + " in the context menu of " + hndPass);
    }
    void Item2_Click(object sender, EventArgs e)
    {
        MenuItem mID = (MenuItem)sender;
        MessageBox.Show("You clicked " + mID.Text + " in the context menu of " + hndPass); ;
    }
}

实现这一目的的一种方法是使用ToolStripDropDown控件在ToolStripDropDown中托管一个ListBox。

这可能需要对AutoClose行为进行一些调整,但它应该让您开始:

首先,在主表单中,向ToolStripDropDropDown项 添加以下行
toolStripDropDownButton1.DropDown = new CustomListDropDown();

然后创建自定义下拉类,如下所示:

public class CustomListDropDown : ToolStripDropDown
{
    private ContextMenuStrip contextMenuStrip1;
    private ToolStripMenuItem toolStripMenuItem1;
    private ToolStripMenuItem toolStripMenuItem2;
    private ToolStripMenuItem toolStripMenuItem3;
    private System.ComponentModel.IContainer components;
    public ListBox ListBox { get; private set; }
    public CustomListDropDown()
    {
        InitializeComponent();
        this.ListBox = new ListBox() { Width = 200, Height = 600 };
        this.Items.Add(new ToolStripControlHost(this.ListBox));
        this.ListBox.ContextMenuStrip = contextMenuStrip1;
        this.ListBox.MouseDown += new MouseEventHandler(ListBox_MouseDown);
        contextMenuStrip1.Closing += new ToolStripDropDownClosingEventHandler(contextMenuStrip1_Closing);
        //add sample items
        this.ListBox.Items.Add("Item1");
        this.ListBox.Items.Add("Item2");
        this.ListBox.Items.Add("Item3");
        this.ListBox.Items.Add("Item4");
    }
    void contextMenuStrip1_Closing(object sender, ToolStripDropDownClosingEventArgs e)
    {
        this.Close();
        this.AutoClose = true;
    }
    void ListBox_MouseDown(object sender, MouseEventArgs e)
    {
        this.AutoClose = false;
        this.ListBox.SelectedIndex = this.ListBox.IndexFromPoint(e.Location);
    }
    private void InitializeComponent()
    {
        this.components = new System.ComponentModel.Container();
        this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
        this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
        this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
        this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem();
        this.contextMenuStrip1.SuspendLayout();
        this.SuspendLayout();
        // 
        // contextMenuStrip1
        // 
        this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
        this.toolStripMenuItem1,
        this.toolStripMenuItem2,
        this.toolStripMenuItem3});
        this.contextMenuStrip1.Name = "contextMenuStrip1";
        // 
        // contextMenuStrip1.ContextMenuStrip
        // 
        this.contextMenuStrip1.Size = new System.Drawing.Size(181, 48);
        // 
        // toolStripMenuItem1
        // 
        this.toolStripMenuItem1.Name = "toolStripMenuItem1";
        this.toolStripMenuItem1.Size = new System.Drawing.Size(180, 22);
        this.toolStripMenuItem1.Text = "toolStripMenuItem1";
        // 
        // toolStripMenuItem2
        // 
        this.toolStripMenuItem2.Name = "toolStripMenuItem2";
        this.toolStripMenuItem2.Size = new System.Drawing.Size(180, 22);
        this.toolStripMenuItem2.Text = "toolStripMenuItem2";
        // 
        // toolStripMenuItem3
        // 
        this.toolStripMenuItem3.Name = "toolStripMenuItem3";
        this.toolStripMenuItem3.Size = new System.Drawing.Size(180, 22);
        this.toolStripMenuItem3.Text = "toolStripMenuItem3";
        // 
        // CustomListDropDown
        // 
        this.Size = new System.Drawing.Size(2, 4);
        this.contextMenuStrip1.ResumeLayout(false);
        this.ResumeLayout(false);
    }
}

在我的测试中,这工作得相当好。

由于ContextMenuStrip派生自ToolStripDropDown,您可以这样做:

    private ContextMenuStrip CopyToContextMenu(ToolStripMenuItem mnuItemSource)
    {
        var mnuContextDestination =  new ContextMenuStrip();
        //Move itens from ToolStripMenuItem to ContextMenuStrip
        while (mnuItemSource.DropDown.Items.Count > 0)
        {
            mnuContextDestination.Items.Add(mnuItemSource.DropDown.Items[0]);
        }
        //Put ContextMenuStrip in ToolStripMenuItem using DropDown property
        mnuItemSource.DropDown = mnuContextDestination;
        return mnuContextDestination;
    }