2012-10-10 17 views
5

右クリックしたときにメニューを表示することで、ユーザーが対話できるようにしたい小さなC#(.NET 4.0)コンソールアプリケーションがあります。システムトレイアイコン。トレイに問題なくアイコンを追加できますが、メニューを表示することはできません。私は次のコードを使用しています:C#コンソールアプリケーションでシステムトレイのアイコンが表示されない

NotifyIcon trayIcon = new NotifyIcon(); 
     trayIcon.Text = "TestApp"; 
     trayIcon.Icon = new Icon(SystemIcons.Application, 40, 40); 

     ContextMenu trayMenu = new ContextMenu(); 

     trayMenu.MenuItems.Add("Blah", item1_Click); 
     trayMenu.MenuItems.Add("Blah2", item1_Click); 
     trayMenu.MenuItems.Add("Blah3", item1_Click); 

     trayIcon.ContextMenu = trayMenu; 
     trayIcon.Visible = true; 

...アイコンをトレイに入れます。ただし、アイコンを右クリックしても何も行われません。私はMenuItems.Addの様々な順列を試しましたが、何も表示されません。私は何かシンプルなものが欠けていると確信しています - どんなアイデア?このメソッドは戻りませんので、あなたはそれを呼び出した後に何もできないということ

Application.Run() 

注:アイコンを作成した後にこれを追加すること

答えて

7

してみてください。つまり、別のスレッドで他のすべての作業を行う必要があります。

OSは、トレイアイコンが右クリックされたことを伝えるメッセージをアプリケーションに送信しますが、トレイアイコンコードには表示されません(これらのメッセージはApplication.Runによって処理されるため応答できません)メニューを開きます。

+1

ソート!実際のコードを別のスレッドに移動するのは簡単です。ありがとうございました! – KenD

0

トレイアイコンマウスクリックのイベントハンドラを追加しましたか?

trayIcon .MouseDown += new MouseEventHandler(trayIcon_MouseDown); 

コンテキストメニューを作成し、trayIcon_MouseDown関数内、次のよう

private void trayIcon_MouseDown (object sender,MouseEventArgs e) 
{ 
    //add you menu items to context menu 
    contextMenu.Items.Add(item); 
    contextMenu.IsOpen = true; 
} 

を行い、これを試してみてください。これがあなたを助けると思う。

6

私はちょうど私がここで共有すると思った...誰かが最終的にApplication.Run()を言いたいことを聞いていた祝福。私はこれを理解しようとすると、あまりにも長く過ごしました。しかし、別のスレッドに他のすべてのコードを配置する代わりに、メインスレッド以外のスレッドでNotifyIcon、メニュー、イベントなどを作成する方法があると私は考えていました。これは、アプリケーションメッセージループが現在のスレッドで動作するようにするため、Application.Run()を含める必要があります。その後、イベントが同じスレッドで作成されたため、Application.Exit()を使用して通知メッセージを閉じても、メインスレッドを続行できます。ここでうまくいけば、これは、彼らがこれをやってのけるするつもりだったか、誰かが疑問に役立つことができます...コンソールアプリケーションのための小さな例です:

class Program 
{ 
    public static ContextMenu menu; 
    public static MenuItem mnuExit; 
    public static NotifyIcon notificationIcon; 

    static void Main(string[] args) 
    { 
     Thread notifyThread = new Thread(
      delegate() 
      { 
       menu = new ContextMenu(); 
       mnuExit = new MenuItem("Exit"); 
       menu.MenuItems.Add(0, mnuExit); 

       notificationIcon = new NotifyIcon() 
       { 
        Icon = Properties.Resources.Services, 
        ContextMenu = menu, 
        Text = "Main" 
       }; 
       mnuExit.Click += new EventHandler(mnuExit_Click); 

       notificationIcon.Visible = true; 
       Application.Run(); 
      } 
     ); 

     notifyThread.Start(); 

     Console.ReadLine();   
    } 

    static void mnuExit_Click(object sender, EventArgs e) 
    { 
     notificationIcon.Dispose(); 
     Application.Exit(); 
    } 

} 
+1

助けてくれたおかげで@bjhuffine。誰かがコピー貼り付けによってコードをすばやくテストしたい場合は、ここで3つのものを追加したかったのです。 1)System.Windows.Forms dllとSystem.Drawing dllへの参照を追加します。 2)上記のアイコン設定行をIcon = new Icon(SystemIcons.Application、40,40)に変更します。3)コンソールソリューションのプロパティを更新し、Windowsフォームとしてコンパイルします。これは通知領域に直接入ります。 – sunder

+0

コンソールがシステムトレイに移動するように、最小化イベントを取得することは可能ですか? –

+0

'MediaTypeNames.Application.Run()'は定義されていません、なぜですか? –

1

ここソリューションです: あなたは、コンソールのGUIのイベントのでApplication.Run()を使用する必要がありますモードが動作しません。 しかし、あなたは、このソリューションを使用することができます。これは新しいスレッドでトライアイコンのセットアップを開始します

System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew(() => ShowTrayIcon()); 

void ShowTrayIcon() 
{ 
    some code with tray icon ... 
} 

を...

関連する問題