42

NotifyIcon を左クリックすると、コンテキスト メニュー (ContextMenuStrip プロパティで設定) も開くようにしたいと考えています。どうすればこれを達成できますか?Click を処理して自分でポジショニングを把握する必要がありますか?
編集:trayIcon.ContextMenuStrip.Show()の結果でメニューを表示することは、いくつかの望ましくない動作です:

NotifyIcon を右クリックした場合と同じ場所にメニューが表示されません (少なくとも、私が実行している Windows 7 では、x 座標と y 座標をタスクバーの場所に設定できないようです)。タスク バーの上に表示されます (大したことではありませんが、一貫性があると便利です)。

メニューが表示されている間、タスク バーに追加のアイコンが追加されます。

メニュー以外の場所をクリックしてもメニューは閉じません (右クリックしてコンテキスト メニューを表示すると、それ以外の場所をクリックすると自動的にコンテキスト メニューが閉じます)。

メニューを呼び出すことはまったく可能ですが、組み込みの右クリックハンドラーがそれを行っていますか?

4

4 に答える 4

90

通常は、MouseClick イベントを処理してクリックを検出し、ContextMenuStrip.Show() メソッドを呼び出します。

    private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) {
        contextMenuStrip1.Show(Control.MousePosition);
    }

しかし、それは実際には正しく機能しません。CMS の外側をクリックしても、CMS は閉じません。根本的な問題は、この KB 記事で説明されている Windows の癖 (別名「バグ」) です。

独自のコードでこの回避策を呼び出すのは非常に苦痛であり、pinvoke は不快です。NotifyIconクラスには、そのShowContextMenu() メソッドにこの回避策がありますが、プライベート メソッドであるため、アクセスが困難になっています。リフレクションはその制限を回避できます。私は 5 年前にこのハッキングを発見しましたが、まだ誰も問題を報告していません。NFI の ContextMenuStrip プロパティを設定し、MouseUp イベントを次のように実装します。

using System.Reflection;
...
    private void notifyIcon1_MouseUp(object sender, MouseEventArgs e) {
      if (e.Button == MouseButtons.Left) {
        MethodInfo mi = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic);
        mi.Invoke(notifyIcon1, null);
      }
    }
于 2010-02-05T17:07:05.267 に答える
2

次のコードを使用して、notifyicon の右クリックと左クリックの両方でコンテキスト メニューを表示します。問題が見つかった場合は、arshad_mcs786@hotmail.com (Islamabd の arshad) にテキスト メッセージを送っ
てください。

    [DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
    public static extern bool SetForegroundWindow(HandleRef hWnd);

    private void notifyIcon1_Click(object sender, EventArgs e)
    {
        SetForegroundWindow(new HandleRef(this, this.Handle));
        int x = Control.MousePosition.X;
        int y = Control.MousePosition.Y;
         x = x - 10;
        y = y - 40;
        this.contextMenuStrip1.Show(x,y );
        //this.PointToClient(Cursor.Position)
    }
于 2014-10-30T05:33:26.753 に答える
2

通知アイコンの onClick イベントを配線してから、クリック時に show を呼び出すことができます

private void wire()
{
     notifyIcon1.Click += new EventHandler(notifyIcon1_Click);
}

void notifyIcon1_Click(object sender, EventArgs e)
 {
    contextMenuStrip1.Show(Cursor.Position);
 }
于 2010-02-05T17:02:04.290 に答える
2

Click ではなく MouseUp を処理すると、どのボタンがクリックされたか、およびクリックの場所がわかります。この場所を ContextMenu を表示する場所として使用できます

notifyIcon.MouseUp += new MouseEventHandler(delegate(object sender, MouseEventArgs e) { contextMenu.Show(e.Location); });
于 2010-02-05T17:03:21.400 に答える