NotifyIcon ContextMenu и слишком много событий кликов - PullRequest
4 голосов
/ 17 октября 2011

Я использую класс NotifyIcon для отображения значка на панели задач. Значок выполняет 2 функции - когда пользователь щелкает левой кнопкой мыши левой кнопкой, он должен отобразить окно, а когда пользователь щелкает правой кнопкой мыши правой кнопкой, он должен отображать контекстное меню. Это прекрасно работает, за исключением того, что окно отображается после того, как пользователь щелкнет опцию в контекстном меню Вот мой код:

contextMenuItems = new List<MenuItem>();
contextMenuItems.Add(new MenuItem("Function A", new EventHandler(a_Clicked)));
contextMenuItems.Add(new MenuItem("-"));
contextMenuItems.Add(new MenuItem("Function B", new EventHandler(b_Clicked)));
trayIcon = new System.Windows.Forms.NotifyIcon();
trayIcon.MouseClick += new MouseEventHandler(trayIcon_IconClicked);
trayIcon.Icon = new Icon(GetType(), "Icon.ico");
trayIcon.ContextMenu = contextMenu;
trayIcon.Visible = true;

Проблема в том, что мое событие trayIcon_IconClicked происходит, когда пользователь выбирает «Функцию A» или «Функцию B». Почему это происходит?

Спасибо, J

Ответы [ 2 ]

3 голосов
/ 17 октября 2011

Назначая контекстное меню элементу управления NotifyIcon, он автоматически ловит щелчок правой кнопкой мыши и открывает там назначенное контекстное меню. Если вы хотите выполнить некоторую логику до фактического отображения контекстного меню, назначьте делегат событию contextMenu.Popup.

...
contextMenu.Popup += new EventHandler(contextMenu_Popup);
...

private void trayIcon_IconClicked(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        //Do something here.
    }
    /* Only do this if you're not setting the trayIcon.ContextMenu property, 
    otherwise use the contextMenu.Popup event.
    else if(e.Button == MouseButtons.Right)
    {
        //Show uses assigned controls Client location to set position, 
        //so must go from screen to client coords.
        contextMenu.Show(this, this.PointToClient(Cursor.Position));
    }
    */
}

private void contextMenu_Popup(object sender, EventArgs e)
{
    //Do something before showing the context menu.
}

Я полагаю, почему всплывающее окно открывается: контекстное меню, которое вы открываете, использует NotifyIcon в качестве целевого элемента управления, поэтому при нажатии на него запускается обработчик щелчка, назначенный для NotifyIcon.

Редактировать: Другой вариант, который следует рассмотреть, - это использовать ContextMenuStrip. NotifyIcon также имеет свойство ContextMenuStrip, и, похоже, с ним связано гораздо больше функциональности (заметил, что я мог бы сделать больше, программируя мудро). Возможно, стоит попробовать, если по какой-то причине все работает не так.

0 голосов
/ 02 апреля 2013

Я столкнулся с той же проблемой. Изменение ContextMenu NotifyIcon на ContextMenuStrip не решает проблему (фактически, когда я изменял ContextMenu, событие Click происходит, когда ContextMenuStrip показывало вместо того, когда пользователь фактически нажимал на один из элементов.

Мое решение проблемы состоит в том, чтобы изменить событие, которое я использовал, чтобы показать контекстное меню левого клика. Вместо того, чтобы использовать обработчик событий Click, я использую MouseUp и проверяю, какая MouseButton нажала.

Создание NotifyIcon (notifyContext - это System.Windows.Forms.ContextMenuStrip)

m_notifyIcon.MouseUp += new Forms.MouseEventHandler(m_notifyIcon_MouseUp);
m_notifyIcon.ContextMenuStrip = notifyContext;

Handling the left click event and show the main contextmenu:

        void m_notifyIcon_MouseUp(object sender, Forms.MouseEventArgs e)
        {
            if (e.Button == Forms.MouseButtons.Left)
            {
                mainContext.IsOpen = ! mainContext.IsOpen;
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...