2011-10-17 7 views
4

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

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 событие вызывается, когда пользователь выбирает «Функция» или «Function B». Почему это происходит?

Спасибо, J

ответ

3

Назначая контекстное меню для управления 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

Спасибо, есть способ сто p он использует NotifyIcon в качестве целевого элемента управления? Или, может быть, даже всплывающее меню вручную? Я пробовал ContextMenu.Show(), но для этого требуется элемент управления как параметр и, похоже, не срабатывает всплывающее событие. – JWood

+1

Выполняете ли вы щелчок правой кнопкой мыши в обработчике кликов события trayIcon_IconClicked? Если да, то нет. Настройка свойства ContextMenu автоматически обрабатывает событие щелчка правой кнопкой мыши любого элемента управления, которому назначено контекстное меню, поэтому вам больше не нужно его обрабатывать. Вот почему он был исключен в событии trayIcon_IconClicked, потому что вы просто дублируете события. Попробуйте и дайте мне знать. – SPFiredrake

+0

Я не обрабатывал клик вручную, я устанавливал свойство ContextMenu, но это дает поведение при запуске события trayIcon_IconClicked, когда пользователь выбирает элемент из контекстного меню. Вышеприведенный пример не работает, поскольку «это» является объектом приложения. Я собираюсь попробовать ContextMenuStrip и посмотреть, дает ли это лучшие результаты. – JWood

0

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

Моего решения проблемы чтобы изменить событие, я использовал, чтобы показать левой кнопкой мыши ContextMenu. Вместо того, чтобы использовать Click EventHandler я использую 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; 
      } 
     } 
Смежные вопросы