Вызвать контекстное меню NotifyIcon - PullRequest
38 голосов
/ 05 февраля 2010

Я хочу, чтобы он был таким, чтобы при щелчке левой кнопкой мыши на NotifyIcon также открывалось контекстное меню (устанавливается с помощью свойства ContextMenuStrip). Как бы я этого достиг? Должен ли я справиться с Click и сам определить положение?
Редактировать: отображение меню с trayIcon.ContextMenuStrip.Show () приводит к нескольким нежелательным действиям:

Меню не отображается в том же месте, как если бы вы щелкнули правой кнопкой мыши по NotifyIcon (кажется, что вы не можете установить координаты x и y в том месте, где находится панель задач, по крайней мере, в Windows 7, что и выполняется ). Он появится над панелью задач (не такая уж большая проблема, но согласованность была бы хорошей).

Пока отображается меню, на панель задач добавлен дополнительный значок.

Щелчок где-то, кроме меню, не закрывает его (тогда как если вы щелкнете правой кнопкой мыши, чтобы вызвать контекстное меню, щелкните в другом месте, где автоматически закроется контекстное меню).

Можно ли вообще вызвать меню, как это делает встроенный обработчик щелчка правой кнопкой мыши?

Ответы [ 4 ]

84 голосов
/ 05 февраля 2010

Обычно вы обрабатываете событие MouseClick для обнаружения щелчка и вызова метода ContextMenuStrip.Show ():

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

Но это на самом деле не работает должным образом, CMS не закроется, когда вы нажмете за ее пределами. Основная проблема заключается в причуде Windows (он же «ошибка»), который описан в этой статье базы знаний .

Вызов этого обходного пути в вашем собственном коде довольно болезненный, пинвока неприятна. Класс 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);
      }
    }
2 голосов
/ 30 октября 2014

используйте следующий код, чтобы отобразить контекстное меню справа и слева, щелкнув по уведомлению. Если вы обнаружите какую-либо проблему, напишите мне по адресу arshad_mcs786@hotmail.com (arshad from Islamabd)
//System.Runtime.InteropServices используют эту ссылку как ссылку

    [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)
    }
2 голосов
/ 05 февраля 2010

Если вы обрабатываете MouseUp, а не Click, вы сможете определить, какая кнопка была нажата, а также местоположение нажатия. Вы можете использовать это местоположение как местоположение для отображения ContextMenu

notifyIcon.MouseUp += new MouseEventHandler(delegate(object sender, MouseEventArgs e) { contextMenu.Show(e.Location); });
2 голосов
/ 05 февраля 2010

Вы можете подключить событие onClick для значка уведомления, а затем вызвать шоу при нажатии

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

void notifyIcon1_Click(object sender, EventArgs e)
 {
    contextMenuStrip1.Show(Cursor.Position);
 }
...