簡體   English   中英

有沒有辦法顯示“阻止”WinForms ContextMenu?

[英]Is there a way to show a “blocking” WinForms ContextMenu?

有沒有辦法顯示ContextMenu並阻止進一步執行,直到選擇了一個項目? 特別是,我想獲得類似於ShowDialog()行為,但是對於ContextMenu

直接的方法不起作用:

ContextMenu cm = new ContextMenu();
cm.MenuItems.Add("1", (s,e) => {value = 1;});
cm.Show(control, location);

因為Click回調不是直接從Show()調用,而是在消息循環處理click事件時稍后調用。

如果你運氣不好, menu會在事件處理之前被垃圾收集,在這種情況下,事件就會無聲地丟失。 (這意味着你不能以這種方式真正使用ContextMenu的局部變量。)

這似乎有效,但感覺“不干凈”:

using (ContextMenu cm = new ContextMenu()) {
    cm.MenuItems.Add("1", (s,e) => {value = 1;});
    cm.Show(control, location);
    Application.DoEvents();
}

有沒有更好的辦法?

對不起,第一個答案。 這是我嘗試過的。 我創建了另一個表單,我將上下文菜單和一個timer.Form2顯示為Form1的模態,然后計時器顯示Form2上的上下文菜單。

請注意,表單2有一些屬性設置:在任務欄中不可見,沒有邊框,大小應該與上下文菜單的大小相等。

希望這可以幫助。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            Form2 ctxForm = new Form2();
            ctxForm.Location = this.PointToScreen(e.Location);
            ctxForm.Size = new Size(0, 0);
            ctxForm.ShowDialog();
        }
    }



}


public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private void exitToolStripMenuItem_Click(object sender, EventArgs e)
    {
        this.Close();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        //show menu once
        contextMenuStrip1.Show(this, PointToClient(Location));
        contextMenuStrip1.Focus();
        timer1.Enabled = false;
    }

    private void contextMenuStrip1_Closed(object sender, ToolStripDropDownClosedEventArgs e)
    {
        this.Close();
    }
}

只是等待菜單不可見。

ContextMenu cm = new ContextMenu();
cm.MenuItems.Add("1", (s,e) => {value = 1;});
cm.Show(control, location);
while (cm.Visible == true) Application.DoEvents();

您可以輕松地阻止ContextMenu的垃圾收集,同時仍然顯示它。

問題是您使用lambda作為菜單項的事件處理程序。 這是一個匿名方法,因此它本身不會附加到任何會導致ContextMenu被引用並因此保持活動的對象實例。 將方法添加到封閉對象,然后創建標准EventHandler。 這樣,封閉實例的存在將使ContextMenu保持活動狀態。 不是簡潔和非常C#1.0,​​但它將解決問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM