2010-02-05 6 views
36

Je veux l'avoir tel que le clic gauche sur NotifyIcon provoque également l'ouverture du menu contextuel (défini avec la propriété ContextMenuStrip). Comment pourrais-je y parvenir? Dois-je gérer Cliquez et comprendre le positionnement moi-même?
Edit: montrant le menu avec des résultats trayIcon.ContextMenuStrip.Show() est quelques comportements indésirables:Appeler le menu contextuel de NotifyIcon

Le menu n'est pas au même endroit que si le clic droit NotifyIcon (il semble que vous ne pouvez pas définir les coeurs x et y à l'endroit où la barre des tâches est, au moins sur Windows 7 qui est ce que je cours). Il apparaîtra au-dessus de la barre des tâches (pas très important, mais la cohérence serait bien).

Lorsque le menu est affiché, une icône supplémentaire est ajoutée à la barre des tâches.

En cliquant ailleurs que sur le menu, vous ne le fermez pas (alors que si vous faites un clic droit pour faire apparaître le menu contextuel en cliquant sur autre où le menu contextuel est automatiquement fermé).

Est-il tout à fait possible d'appeler simplement le menu, mais le gestionnaire de clic droit intégré le fait?

Répondre

82

Vous devriez normalement gérer l'événement MouseClick pour détecter le clic et appeler la méthode ContextMenuStrip.Show():

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

Mais ce doesn ne fonctionne pas correctement, le CMS ne se ferme pas lorsque vous cliquez en dehors de celui-ci. Le problème sous-jacent est une anomalie de Windows (également appelée "bogue") décrite dans this KB article.

Invoquer cette solution de contournement dans votre propre code est assez pénible, le pinvoke est désagréable. La classe NotifyIcon a cette solution de contournement dans son ShowContextMenu() method, ils ont juste rendu difficile d'y accéder car c'est une méthode privée. La réflexion peut contourner cette restriction. J'ai découvert ce hack il y a 5 ans et personne n'a encore signalé de problème. Définissez la propriété ContextMenuStrip du NFI et mettre en œuvre l'événement MouseUp comme ceci:

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 - pas à la fin d'éditer les commentaires :) Vous avez des astuces pour résoudre plus la solution de contournement ApplicationContext. Rechercher mes réponses pour SetVisibleCore. –

+0

Cette solution n'utilise pas la possibilité d'assigner la propriété 'NotifyIcon'' menu' à l'objet ContextMenuStrip; et par conséquent, il fait un hack trop moche pour résoudre un problème qui ne devrait pas se produire en premier lieu. S'il vous plaît voir http://stackoverflow.com/questions/132612/show-a-contextmenustrip-without-it-showing-in-the-taskbar pour plus d'informations. –

+5

C'est un non-sens complet. –

2

Vous pouvez câbler un événement onClick pour notifier l'icône puis appelez show dans le clic à

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

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

Si vous gérez MouseUp plutôt que Cliquez, vous serez en mesure de dire quel bouton a été cliqué, ainsi que le location du clic. Vous pouvez utiliser cet emplacement comme emplacement pour montrer la ContextMenu

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

utiliser le code suivant pour afficher le menu contextuel à la fois à droite et cliquez à gauche sur NotifyIcon, si vous trouvez un problème texte me puis à arshad_mcs786 @ hotmail. com (Arshad de Islamabd)
//System.Runtime.InteropServices utilisent comme référence 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) 
    }