2009-07-01 26 views
11

Tengo una aplicación .Net 3.5 C# Winforms. No tiene GUI como tal, solo NotifyIcon con ContextMenu.Problema con NotifyIcon no desaparece de la aplicación Winforms

He tratado de establecer el NotifyIcon como visible = false y disponer de ella en caso Application_Exit, de la siguiente manera:

 if (notifyIcon != null) 
     { 
      notifyIcon.Visible = false; 
      notifyIcon.Dispose(); 
     } 

La aplicación obtiene al código dentro de los corchetes, pero lanza una referencia nula excepción cuando intenta establecer Visible = falso.

He leído en algunos lugares para ponerlo en el evento de cierre del formulario, pero ese código nunca se ve afectado (¿tal vez porque no tengo un formulario que se muestre como tal?).

¿Dónde puedo poner este código para que realmente funcione? Si no lo coloco, obtengo el molesto ícono persistente en la bandeja hasta que mueva el mouse sobre él.

Saludos.

EDITAR

Sólo algo extra me he dado cuenta ...........

estoy usando ClickOnce en la aplicación ....... ..si acabo de salir de la aplicación a través del ContextMenu en NotifyIcon, no se registra ninguna excepción.

Justo cuando el evento Application_Exit es despedido después de la applicaiton ha comprobado para una actualización aquí ..

private void CheckForUpdate() 
{ 
    EventLogger.Instance.LogEvent("Checking for Update"); 
    if (ApplicationDeployment.IsNetworkDeployed && ApplicationDeployment.CurrentDeployment.CheckForUpdate()) 
    { 
     EventLogger.Instance.LogEvent("Update available - updating"); 
     ApplicationDeployment.CurrentDeployment.Update(); 
     Application.Restart(); 
    } 
} 

¿Esto ayuda?

Respuesta

3

Este código funciona para mí, pero no sé cómo se está manteniendo viva su aplicación, así que ... sin más preámbulos:

using System; 
using System.Drawing; 
using System.Windows.Forms; 

static class Program 
{ 
    static System.Threading.Timer test = 
     new System.Threading.Timer(Ticked, null, 5000, 0); 

    [STAThread] 
    static void Main(string[] args) 
    { 
     NotifyIcon ni = new NotifyIcon(); 
     ni.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath); 
     ni.Visible = true; 

     Application.Run(); 
     ni.Visible = false; 
    } 

    static void Ticked(object o) { 
     Application.Exit(); 
    } 
} 
0

varias veces A veces Application_Exit caso puede elevarse sólo hay que poner notifyIcon = null; al final

if (notifyIcon != null) 
{ 
    notifyIcon.Visible = false; 
    notifyIcon.Dispose(); 
    notifyIcon = null; 
} 
+0

realidad, ahora que lo pienso, me gustaría recomendar en contra de usar este evento para esto porque es posible tener varios Application.Run() bucles de ir en diferentes subprocesos y todos activarán un evento de Salida que podría hacer que el ícono desaparezca prematuramente. –

+0

Totalmente de acuerdo con usted! Prefiero no usar este evento en mis aplicaciones para ningún propósito de limpieza. Sin embargo, es la respuesta más simple a la pregunta "por qué este código arroja una excepción". En cuanto a mis ideas de cómo diseñar este código de otra manera, podría proponer crear una clase desechable envoltorio alrededor de notifyIcon, por lo que controlará la vida útil de notifyIcon. y luego escriba usando (nuevo NotifyIconController()) {Application.Run()}; o algo como esto –

3

Esto es lo que estoy haciendo en WPF.

Estoy usando esto junto con Minimize to tray sample app de David Anson, que le permite conectar un icono de bandeja a una ventana (puede tener varias ventanas abiertas).

Acabo de agregar este código al constructor para MinimizeToTrayInstance.

_window.Closed += (s, e) => 
{ 
     if (_notifyIcon != null) 
     { 
      _notifyIcon.Visible = false; 
      _notifyIcon.Dispose(); 
      _notifyIcon = null; 
     } 
}; 
+0

Evento de cierre de ventana, funcionó para mí. En App_Exit arroja un error al desechar notifyIcon. – Sunil

+1

simplemente envuélvelo en una captura de prueba e ignore la excepción –

11

En Windows 7, también tuve que establecer la propiedad Icon en nulo. De lo contrario, el icono permanecía en la ventana emergente de "iconos ocultos" de la bandeja después de que la aplicación se cerró. HTH alguien.

// put this inside the window's class constructor 
Application.ApplicationExit += new EventHandler(this.OnApplicationExit); 


     private void OnApplicationExit(object sender, EventArgs e) 
     { 

      try 
      { 
       if (trayIcon != null) 
       { 
        trayIcon.Visible = false; 
        trayIcon.Icon = null; // required to make icon disappear 
        trayIcon.Dispose(); 
        trayIcon = null; 
       } 

      } 
      catch (Exception ex) 
      { 
       // handle the error 
      } 
     } 
+0

lo mismo es cierto para Windows 8. buena captura :) – Ovais

+2

Esta es la solución de trabajo. Gracias. –

0

¿Ha anulado el método de disponer del objeto donde se ha inicializado el NotifyIcon disponer también la NotifyIcon?

protected override void Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
     notifyIcon.Dispose(); 
     notifyIcon = null; 
    } 
    base.Dispose(disposing); 
} 
0

Este código funcionó para mí

this.Closed += (a, b) => 
      { 
       if (notifyIcon1 != null) 
       { 
        notifyIcon1.Dispose(); 
        notifyIcon1.Icon = null; 
        notifyIcon1.Visible = false; 
       } 
      }; 
Cuestiones relacionadas