2010-02-05 17 views
36

Quiero tenerlo de modo que al hacer clic izquierdo en NotifyIcon también se abra el menú contextual (establecido con la propiedad ContextMenuStrip). ¿Cómo lograría esto? ¿Debo manejar Click y averiguar el posicionamiento por mi cuenta?
Editar: muestra el menú con trayIcon.ContextMenuStrip.Show() resultados es de unos comportamientos indeseables:Invocar el menú de contexto de NotifyIcon

El menú no se muestra en el mismo lugar como si clic derecho en el NotifyIcon (parece que no se puede establecer las coordenadas xey para donde está la barra de tareas, al menos en Windows 7, que es lo que estoy ejecutando). Aparecerá encima de la barra de tareas (no es un gran problema, pero la consistencia sería agradable).

Mientras se muestra el menú, se agrega un icono adicional a la barra de tareas.

Al hacer clic en un sitio que no sea el menú no se cierra (mientras que si hace clic derecho para abrir el menú contextual, haga clic en else donde se cierra automáticamente el menú contextual).

¿Es posible invocar el menú sin embargo, el controlador de clic derecho integrado lo está haciendo?

Respuesta

82

Que normalmente controlar el evento MouseClick para detectar el clic y llamar a la ContextMenuStrip.Show) método (:

private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) { 
     contextMenuStrip1.Show(Control.MousePosition); 
    } 

Pero eso no De hecho, no funciona correctamente, el CMS no se cerrará cuando haga clic fuera de él. El problema subyacente es una peculiaridad de Windows (también conocida como "error") que se describe en this KB article.

Invocar esta solución en su propio código es bastante doloroso, el pinvoke es desagradable. La clase NotifyIcon tiene esta solución en su ShowContextMenu() method, simplemente hicieron que sea difícil de acceder, ya que es un método privado. La reflexión puede eludir esa restricción. Descubrí este truco hace 5 años y nadie informó un problema con él. Establecer propiedad de ContextMenuStrip del NFI y poner en marcha el evento MouseUp así:

using System.Reflection; 
... 
    private void notifyIcon1_MouseUp(object sender, MouseEventArgs e) { 
     if (e.Button == MouseButtons.Left) { 
     MethodInfo mi = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic); 
     mi.Invoke(notifyIcon1, null); 
     } 
    } 
+0

@msorens - no es demasiado tarde para editar :) hay otros trucos para resolver la solución Application Context. Busque mis respuestas para SetVisibleCore. –

+0

Esta solución no está utilizando la posibilidad de asignar la propiedad '' NotifyIcon' 'menu' al objeto ContextMenuStrip; y por lo tanto, está haciendo un truco demasiado feo para resolver un problema que no debería ocurrir en primer lugar. Consulte http://stackoverflow.com/questions/132612/show-a-contextmenustrip-without-it-showing-in-the-taskbar para obtener más información. –

+5

Eso no tiene sentido. –

2

Puede cablea en un evento de clic para notificar icono a continuación, llamar espectáculo en el al hacer clic

private void wire() 
{ 
    notifyIcon1.Click += new EventHandler(notifyIcon1_Click); 
} 

void notifyIcon1_Click(object sender, EventArgs e) 
{ 
    contextMenuStrip1.Show(Cursor.Position); 
} 
2

Si usted maneja MouseUp en lugar de Click, usted será capaz de decir qué botón se hizo clic, así como el location del clic. Puede utilizar esta ubicación como la ubicación para mostrar el ContextMenu

notifyIcon.MouseUp += new MouseEventHandler(delegate(object sender, MouseEventArgs e) { contextMenu.Show(e.Location); }); 
2

utilizar el siguiente código para mostrar el menú contextual de la derecha y la izquierda, haga clic en NotifyIcon, si usted encuentra cualquier problema, entonces me de texto en arshad_mcs786 @ hotmail. com (arshad de Islamabd)
//System.Runtime.InteropServices utilizan como referencia Thi

[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] 
    public static extern bool SetForegroundWindow(HandleRef hWnd); 

    private void notifyIcon1_Click(object sender, EventArgs e) 
    { 
     SetForegroundWindow(new HandleRef(this, this.Handle)); 
     int x = Control.MousePosition.X; 
     int y = Control.MousePosition.Y; 
     x = x - 10; 
     y = y - 40; 
     this.contextMenuStrip1.Show(x,y); 
     //this.PointToClient(Cursor.Position) 
    } 
Cuestiones relacionadas