web-dev-qa-db-fra.com

Invoquez le menu contextuel de notifyicon

Je veux que ce soit de telle sorte que le clic gauche sur le notificon provoque également le menu contextuel (défini avec la propriété contextmenRip) pour s'ouvrir également. Comment pourrais-je y arriver? Dois-je gérer des clic et comprendre moi-même?
[.____] Edit: Afficher le menu avec Trayicon.ContexTMengrip.show () Les résultats sont quelques comportements indésirables:

Le menu n'est pas affiché au même endroit que si vous cliquez avec le bouton droit de la souris sur le bouton droit de la souris (il apparaît que vous ne pouvez pas définir les coordonnées X et Y sur l'endroit où la barre des tâches est, du moins sur Windows 7, ce que je suis en cours d'exécution). Il apparaîtra au-dessus de la barre des tâches (pas si grosse affaire, mais la cohérence serait bien).

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

En cliquant quelque part autre que le menu ne le fermez pas (alors que si vous cliquez avec le bouton droit de la souris pour afficher le menu contextuel, cliquez sur autre où se ferme automatiquement le menu contextuel).

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

40
BarrettJ

Vous alliez normalement gérer l'événement de MouseClick pour détecter le clic et appeler la méthode contextmengrip.show ():

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

Mais cela ne fonctionne pas vraiment correctement, le CMS ne se ferme pas lorsque vous cliquez en dehors de cela. Le problème sous-jacent est une Windows Quirk (AKA "Bug") décrit dans cet article de KB .

Invoquant cette solution de contournement dans votre propre code est assez douloureux, le Pinvoke est désagréable. La classe NOTIFYICON a cette solution de contournement dans sa méthode SHOWCONTEXTEXTMENU () , ils ont juste rendu difficile l'accès, car il s'agit d'une méthode privée. La réflexion peut contourner cette restriction. J'ai découvert ce piratage il y a 5 ans et personne n'a signalé un problème avec ça. Définissez la propriété contextMentrip de NFI et implémentez l'événement MouseUp comme celui-ci:

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);
      }
    }
86
Hans Passant

utilisez le code suivant pour afficher le menu contextuel sur le bouton droit et gauche sur NOTIFYICON, si vous trouvez un problème, envoyez-moi un sujet sur [email protected] (Arshad de Islamabd)
[.____] // system.runtime.interopservices utilise Thi comme référence

    [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)
    }
2
Arshad

Vous pouvez filer dans un événement ONCLICK pour notifier l'icône, puis appelez Afficher en un clic

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

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

Si vous gérez MouseUp plutôt que de cliquer, vous pourrez dire quel bouton a été cliqué, ainsi que le emplacement du clic. Vous pouvez utiliser cet emplacement comme emplacement pour afficher le contexteMenu

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