Открытие ContextMenu из ToolStripMenuItem - PullRequest
2 голосов
/ 23 ноября 2011

Я пытаюсь имитировать поведение, например, проводника Windows и то, как элементы «Избранное» могут запускать контекстное меню.

Я сейчас использую:

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

Это происходит в событии MouseDown ToolStripMenuItem. Проблема в том, что меню закрывается сразу после щелчка правой кнопкой мыши, и я не знаю, как приостановить его, пока открыто контекстное меню.

Я пытался извлечь из ToolStripMenuItem и переопределить MouseDown / MouseUp, но я не могу понять, как держать его открытым при нажатии.

Есть ли хороший способ сделать это?

Ответы [ 2 ]

1 голос
/ 25 октября 2013

Это то, с чем мне повезло, это более прямолинейно:

    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); ;
    }
}
0 голосов
/ 04 декабря 2011

Один из способов добиться этого - использовать элемент управления ToolStripDropDown для размещения ListBox внутри ToolStripDropDown.

Для этого может потребоваться некоторая настройка поведения 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);

    }
}

В моих тестах это работало достаточно хорошо. Дайте мне знать, как это происходит.

...