2011-12-19 10 views
0

Windows UIの通知領域にアイコンを配置するアプリケーションでプラグイン(System.ComponentModel.Compositionを使用)を使用しています。私はそのアイコンのコンテキストメニューに項目をクリックすると今、Clickハンドラが呼び出されていませんNotifyIconに添付されたContextMenuでクリックイベントが発生しました

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) { 
    // ... 
} 


興味深いことに、アイコンをもう一度右クリックすると(メニュー項目をクリックした後に)、以前にクリックされたMenuItemのハンドラが呼び出されます。Clickアイコンを左クリックまたはホバーしても、この手順は実行されません。

何が起こっていますか?

更新:私の問題はthis questionに関連していると強く感じています。しかし、私はまだそれを私のプラグイン/アプリケーションにどのように適用できるかを理解しようとしています。

+0

自分でコンテキストメニューを表示するなど、珍しいことはありますか?メニューの外側をクリックすると、それは消えますか? –

+0

@ハンスパッサント:いいえ、私は何か珍しいことはしていないと思います。メニューのオープンは、NotifyIconによって処理されます。メニューの外側をクリックすると、(期待どおり)消えます。 –

答えて

0

問題は、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 
    } 
} 

素晴らしいと思われます。

関連する問題