web-dev-qa-db-fra.com

NotifyIcon reste dans le bac même après la fermeture de l'application mais disparaît au survol de la souris

Il y a beaucoup de questions sur SO qui pose le même doute . La solution pour cela est de définir 

notifyIcon.icon = null et appelez Dispose pour cela dans l'événement FormClosing.

Dans ma demande, il n'existe pas de formulaire de ce type, mais l'icône de notification permet de mettre à jour l'événement . Lors de la création, je masque mon formulaire et crée la propriété ShowInTaskbar, false. Par conséquent, je ne peux pas avoir d'événements "FormClosing" ou "FormClosed".

Si cette application obtient que l'événement se termine, il appelle Process.GetCurrentProcess().Kill(); pour quitter.

J'ai ajouté notifyIcon.icon = null ainsi que Dispose avant de tuer, mais l'icône reste toujours dans la barre des tâches jusqu'à ce que je la survole avec la souris.

EDIT: Si je suppose que ce problème est dû à l'appel de GetCurrentProcess().Kill(), existe-t-il un moyen élégant de quitter l'application qui efface toutes les ressources et supprime l'icône de la barre d'état système?.

53
Swanand

Vous pouvez soit définir

notifyIcon1.Visible = false;

OR

notifyIcon.Icon = null;

dans l'événement de clôture du formulaire.

45
Jason Dias

La seule solution qui a fonctionné pour moi a été d’utiliser l’événement Fermé et de masquer et d’éliminer l’icône.

icon.BalloonTipClosed += (sender, e) => { 
                                            var thisIcon = (NotifyIcon)sender;
                                            thisIcon.Visible = false;
                                            thisIcon.Dispose(); 
                                        };
12
The Muffin Man

Utiliser notifyIcon.Visible = False dans l'événement FormClosing

7
Ismael

J'ai essayé ce code. Je pense que c'est plus facile. Je vais l'écrire pour plusieurs outils ou événements. J'espère que cela vous sera utile.

Utilisez ce code lorsque vous souhaitez le faire lorsque vous appuyez sur le bouton Quitter ou Fermer:

    private void ExitButton_Click(object sender, EventArgs e)
    {
            notifyIcon.Dispose;
            Application.Exit();        //   or   this.Close();
    }

Utilisez ce code lorsque vous souhaitez le faire lorsque le formulaire se ferme:

    private void Form1_FormClosing(object sender, EventArgs e)
    {
            notifyIcon.Dispose;
            Application.Exit();        //   or   this.Close();
    }

Le code important est le suivant:

    notifyIcon.Dispose;
5
Pouya

Les composants doivent simplement être disposés dans le bon ordre, comme ceci:

NotifyIcon.Icon.Dispose();

NotifyIcon.Dispose();

Ajoutez ceci à l'événement de clôture MainWindow.

J'espère que cela aidera.

3
Shim-Sao

C'est un comportement normal, malheureusement; c'est dû au fonctionnement de Windows. Vous ne pouvez vraiment rien faire à ce sujet.

Voir Problème avec NotifyIcon ne disparaissant pas sur Winforms App pour certaines suggestions, mais aucune d’entre elles n’a jamais fonctionné pour moi.

Voir également L'icône de notification reste dans la zone de notification à la fermeture de l'application

Microsoft a marqué ceci comme "ne résoudra pas" sur Microsoft Connect.

2
Matthew Watson

Je ne pense pas que WPF ait son propre NotifyIcon, n'est-ce pas? Si vous utilisez une tierce partie Harcodet.Wpf.TaskbarNotification, essayez ceci:

Afin d'éviter que mon application ne se ferme lorsque la fenêtre est fermée (en arrière-plan), j'ai séparé la logique de fermeture de la fenêtre (en appuyant sur le bouton x en haut à droite) et en l'éteignant (via le menu contextuel). Pour que cela fonctionne, réglez _isExplicitClose sur true dans votre menu contextuel. Sinon, il ne vous reste plus qu'à masquer la fenêtre et continuer à fonctionner.

Ce que cela fait est, lors de la fermeture explicite, de masquer l’icône de la barre des tâches et le formulaire avant la fermeture. De cette façon, l’icône ne reste pas après la fermeture de l’application.

private bool _isExplicitClose;
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    base.OnClosing(e);

    if (!_isExplicitClose)
    {
        e.Cancel = true;
        Hide();
    }
}

protected void QuitService(object sender, RoutedEventArgs e)
{
   _isExplicitClose = true;
   TaskbarIcon.Visibility = Visibility.Hidden;
   Close();
}
2
Sinaesthetic

Essayez Application.DoEvents(); après avoir défini notifyIcon.Icon sur null et avoir éliminé:

notifyIcon.Icon = null;
notifyIcon.Dispose();
Application.DoEvents();

Et considérons Environment.Exit(0); au lieu de Process.GetCurrentProcess().Kill().

1
Cubinator73

je peux dire que vous pouvez résoudre le problème simplement en utilisant la méthode .dispose (), mais cela n’est pas appelé si vous supprimez le processus au lieu de quitter l’application.

veuillez vous référer à Application.Exit si vous avez créé une application Windows Form simple, sinon référez-vous à Environment.Exit qui est plus général.

1
Lanello

J'ai eu exactement le même problème que toi. 

Les moyens appropriés sont d'envoyer un message WM_CLOSE à un processus.
J'utilise le code c # que j'ai trouvé dans cet article.
http://social.msdn.Microsoft.com/Forums/vstudio/en-US/82992842-80eb-43c8-a9e6-0a6a1d19b00f/terminating-a-process-in-a-friendly-way

0
victor

La bonne réponse a déjà été donnée. Mais vous devez également prévoir un délai, par exemple avec une minuterie. Ce n’est qu’alors que l’application peut toujours supprimer l’icône en arrière-plan.

private System.Windows.Forms.Timer mCloseAppTimer;
private void ExitButton_Click(object sender, EventArgs e) 
{ 
    notifyIcon.Visible = false; notifyIcon.Dispose; 
    mCloseAppTimer = new System.Windows.Forms.Timer(); 
    mCloseAppTimer.Interval = 100; 
    mCloseAppTimer.Tick += new EventHandler(OnCloseAppTimerTick); 
} 
private void OnCloseAppTimerTick(object sender, EventArgs e) 
{ 
    Environment.Exit(0); // other exit codes are also possible 
}
0
Michael Petöfalvi

éditez les codes de ... Designer.cs comme ci-dessous. 

        protected override void Dispose(bool disposing)
           {
           if (disposing )
               {
               this.notifyicon.Dispose();
               }
           base.Dispose(disposing);
           }
0
Can DOGRU

J'ai essayé toutes ces techniques et aucune d'entre elles n'a fonctionné pour moi. Après y avoir réfléchi pendant un moment, je me suis rendu compte que l'application créant le "ballon" était en train de disparaître avant d'avoir eu la possibilité de disposer du ballon. J'ai ajouté une boucle while juste avant Application.Exit() contenant une commande Application.DoEvents(). Cela a permis à mon NotifyIcon1_BalloonTipClosed de finir de se débarrasser de l'icône avant de quitter.

while (notifyIcon1.Visible)
{
    Application.DoEvents();
}
Application.Exit();

Et la méthode de fermeture des astuces: (Vous devez inclure le thisIcon.visible = false pour que cela fonctionne)

private void NotifyIcon1_BalloonTipClosed(object sender, EventArgs e)
{
    var thisIcon = (NotifyIcon)sender;
    thisIcon.Icon = null;
    thisIcon.Visible = false;
    thisIcon.Dispose();
}
0
Terrence Meehan