簡體   English   中英

附加到NotifyIcon的ContextMenu中的Click事件被延遲

[英]Click event delayed in ContextMenu attached to NotifyIcon

我正在為應用程序開發一個插件(使用System.ComponentModel.Composition ),以將圖標放置在Windows UI的通知區域中。

trayMenu.MenuItems.Clear();

// Create context menu items
foreach( IJob job in jobs ) {
  MenuItem menuItem = new MenuItem( job.Name ) {Tag = job};
  menuItem.Click += MenuItemClick;
  trayMenu.MenuItems.Add( menuItem );
}

private void MenuItemClick( object sender, EventArgs e ) {
  // ...
}

現在,當我單擊該圖標的上下文菜單中的某個項目時,不會調用Click處理程序。
但是,有趣的是,當我再次右鍵單擊圖標(單擊菜單項后)時,將調用先前單擊的MenuItemClick處理程序。 左鍵單擊或將鼠標懸停在圖標上不會觸發此步驟。

到底是怎么回事?

更新 :我很感到我的問題與這個問題有關 但我仍在嘗試弄清楚如何將其應用於我的插件/應用程序。

據我了解,問題在於沒有為NotifyIcon處理任何窗口消息(或者至少沒有我喜歡/需要的消息數量)。

我通過從Form繼承並為插件運行另一個消息泵解決了該問題。

using System;
using ...

namespace JobTracker.Tray {
  [Export( typeof( IJobTrackerPlugin ) )]
  public class TrayPlugin : Form, IJobTrackerPlugin {

    #region Plugin Interface
    [Import( typeof( IJobTracker ) )]
#pragma warning disable 649
      private IJobTracker _host;
#pragma warning restore 649
    private IJobTracker Host {
      get { return _host; }
    }

    public void Initialize() {
      trayMenu = new ContextMenu();
      trayMenu.MenuItems.Add( "Exit", OnExit );

      trayIcon = new NotifyIcon();
      trayIcon.Icon = new Icon( SystemIcons.Application, 32, 32 );

      trayIcon.ContextMenu = trayMenu;

      // Show the proxy form to pump messages
      Load += TrayPluginLoad;
      Thread t = new Thread(
        () => {
          ShowInTaskbar    = false;
          FormBorderStyle  = FormBorderStyle.None;
          trayIcon.Visible = true;
          ShowDialog();
        } );
      t.Start();
    }

    private void TrayPluginLoad( object sender, EventArgs e ) {
      // Hide the form
      Size = new Size( 0, 0 );
    }
    #endregion

    private NotifyIcon trayIcon;    
    private ContextMenu trayMenu;

    private void OnExit( object sender, EventArgs e ) {
      Application.Exit();
    }

    #region Implementation of IDisposable

    // ...

    private void DisposeObject( bool disposing ) {
      if( _disposed ) {
        return;
      }
      if( disposing ) {
        // Dispose managed resources.
        if( InvokeRequired ) {
          EndInvoke( BeginInvoke( new MethodInvoker( Close ) ) );
        } else {
          Close();
        }
        trayIcon.Dispose();
        trayMenu.Dispose();
      }
      // Dispose unmanaged resources.
      _disposed = true;
    }
    #endregion
  }
}

似乎工作很棒。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM