2012-10-10 55 views
5

Tengo una pequeña aplicación de consola C# (.NET 4.0) que me gustaría que el usuario pueda interactuar mostrando un menú cuando hacen clic derecho el ícono de la bandeja del sistema. Puedo agregar un icono a la bandeja sin problemas, pero simplemente no puedo hacer que aparezca el menú. Estoy usando el siguiente código:Icono de la bandeja del sistema con C# Console La aplicación no mostrará el menú

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; 

... que coloca el icono en la bandeja. Sin embargo, al hacer clic derecho en el ícono no se hace nada. Probé varias permutaciones de MenuItems.Add, pero nada hará que aparezca el menú. Estoy seguro de que me está perdiendo algo simple. ¿Alguna idea de qué?

Respuesta

7

Trate de añadir esto después de crear el icono:

Application.Run() 

Tenga en cuenta que este método no va a volver, por lo que no se puede hacer nada después de llamar a la misma. Esto significa que tendrá que hacer todo su otro trabajo en un hilo separado.

Lo que sucede es que el sistema operativo envía un mensaje a su aplicación diciéndole que el ícono de la bandeja ha sido clic derecho, pero el código del icono de la bandeja nunca lo ve (porque estos mensajes son procesados ​​por Application.Run) y no puede responder abriendo el menú.

+1

Ordenado! Mover el código real a otro subproceso debería ser lo suficientemente fácil. ¡Gracias! – KenD

0

¿Ha agregado el controlador de eventos para el icono de la bandeja clic del mouse?

trayIcon .MouseDown += new MouseEventHandler(trayIcon_MouseDown); 

crear menús de contexto y hacer así dentro de la función trayIcon_MouseDown

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

Prueba esto. Piensa que esto te ayudará.

6

Sólo pensé en compartir aquí ... qué bendición fue escuchar a alguien finalmente mencionar Application.Run(). He pasado demasiado tiempo tratando de resolver esto. Sin embargo, pensé que compartiría que una alternativa para colocar todo el otro código en otro hilo sería crear NotifyIcon, menú, eventos, etc. en un hilo que no sea el hilo principal. Esto debería incluir Application.Run() ya que esto permite que el bucle de mensaje de aplicación estándar funcione en el actual subproceso. Luego, dado que los eventos se crearon en el mismo subproceso, Application.Exit() se puede usar para cerrar los mensajes de notificación pero aún permitir que el hilo principal continúe. He aquí un pequeño ejemplo para una aplicación de consola ... espero que esto puede ayudar a alguien preguntándose cómo iban a sacar esto adelante:

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

Gracias @bjhuffine que ayudó. Quería agregar tres cosas aquí si alguien quiere probar el código rápidamente copiando y pegando. 1) Agregue referencia a System.Windows.Forms dll y System.Drawing dll. 2) Cambie la línea de configuración del icono anterior a Icon = new Icon (SystemIcons.Application, 40, 40), 3) Actualice las propiedades de su solución de consola y compílela como Windows Forms, directamente entrará en el área de notificación. – sunder

+0

Es posible obtener el evento de minimizar, para que la consola vaya a la bandeja del sistema? –

+0

'MediaTypeNames.Application.Run()' no está definido, ¿por qué? –

1

Aquí está la solución: Usted tiene que usar Application.Run() porque los eventos de interfaz gráfica de usuario en la consola modo no funciona. Pero usted puede usar esta solución:

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

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

Esto iniciará la configuración del icono de intento en nuevo hilo ...

Cuestiones relacionadas