2011-12-06 16 views
4

ContextMenuを表示し、アイテムが選択されるまでさらに実行をブロックする方法はありますか?特に、私はShowDialog()に似ているが、ContextMenuに似た行動をしたい。「ブロッキング」WinForms ContextMenuを表示する方法はありますか?

簡単な方法は動作しません:

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

メッセージループは、クリックイベントを処理するときClickコールバックがShow()から直接呼び出す代わりに、いくつかの後の時点でされていないため。

不運な場合は、イベントが処理される前にmenuがガベージコレクションされます。この場合、イベントはただ静かに失われます。 (あなたが本当にこの方法でContextMenu秒間ローカル変数を使用することはできません意味。)

これが動作しているようですが、「汚れた」感じている:

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

良い方法はありますか?

+1

いいえ、Show()コールの後にCollapseイベントのイベントハンドラに移動したコードはすべて移動します。または、ShowDialogを使用できるようにフォームを使用します。 –

答えて

0

ContextMenuのガベージコレクションがまだ表示されている間、簡単にガベージコレクションを防ぐことができます。

問題は、メニュー項目のイベントハンドラとしてラムダを使用していることです。これは の匿名メソッドであり、ContextMenuを参照して生き続けるようにするオブジェクトインスタンスにアタッチされません。囲みオブジェクトにメソッドを追加し、標準のEventHandlerを作成します。そのようにすると、囲むインスタンスの存在によってContextMenuが生き続けることになります。簡潔ではなく、非常にC#1.0でも問題は解決します。

1

申し訳ありませんが、最初の答えです。ここで私が試したことがあります。別のFormを作成し、コンテキストメニューを作成し、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(); 
    } 
} 
0

メニューが表示されないようにしてください。

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