2009-02-06 21 views
10

Tengo un programa que solo necesita NotifyIcon para que funcione como estaba previsto. Así que he estado tratando de ocultar el formulario principal cuando se inicia el programa.Ocultar formulario en el inicio

En frmMain_Load, he intentado tanto

this.Hide(); 
this.Visible = false; 

sin éxito.

Funcionan en otros métodos, como en el método NotifyIcon_MouseClick, pero quiero que se oculte en Load.

vi en otra pregunta aquí en SO donde Matias sugirió esto:

BeginInvoke(new MethodInvoker(delegate 
{ 
    Hide(); 
})); 

Esto funciona, pero cuando inicio el programa que se puede ver la forma de parpadear muy rápido. Es mejor que nada, pero me pregunto si hay alguna mejor solución para esto.

Gracias.

Respuesta

15
// In Your Program.cs Convert This 
static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    Application.Run(new Form1()); 
} 

// To This 
static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    Form1 TheForm = new Form1(); 
    Application.Run(); 
} 

// Call Application.Exit() From Anywhere To Stop Application.Run() Message Pump and Exit Application 
+0

Esta solución tiene un problema. En este caso, cuando cierra el formulario, los eventos 'FormClose' y' FormClosing' no se subirán. – parseh

+0

¿Cómo se puede hacer que la aplicación salga cuando se cierra el formulario con el botón X? –

+0

Una mejor solución es crear un 'ApplicationContext', y pasarle una instancia a' Application.Run() ', que gestiona el ciclo de vida del formulario evitando así la necesidad de llamar' Application.Exit() 'a otro lugar. –

2

No llame a Show o ShowDialog en su formulario, puede hacer que su aplicación ejecute una clase personalizada que luego crea una instancia de un formulario y no muestra o crea una instancia NotifyIcon y maneja todo desde allí.

+0

Usted también puede simplemente llamar Application.Run() sin ningún parámetro. Cuando su aplicación haya terminado, llame a la Aplicación.Salida(); – VBNight

+0

Esto no funcionará si necesita recibir algunas notificaciones de eventos, como eventos de energía, etc., donde realmente necesita un formulario (invisible) para obtenerlas. –

+0

Gracias por su respuesta. ¿Tengo que crear mi propia clase de formulario personalizada o podría simplemente eliminar la línea Mostrar() en algún lugar? Si tengo que crear mi propia clase personalizada, ¿cómo hago eso? He estado buscando en el código pero no encuentro nada interesante. – sippa

5

hay una manera más fácil, si el programa tiene el defecto de Visual Studio genera archivo Program.cs:

[STAThread] 
static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault (false); 
    Application.Run (new MainForm()); 
} 

el simple hecho de llamar Run será, de hecho, hacer que la forma visible. Trata de hacer lo siguiente en las propiedades de su formulario:

  1. Establecer WindowState a Minimized
  2. Establecer ShowInTaskbar a false

Esto debe hacer el truco!

+0

¡Gracias por su respuesta! Olvidé mencionar que ya lo intenté de esta manera. Funcionó parcialmente, pero pude ver la barra de título del formulario en la esquina inferior izquierda, así que quiero hacerlo de otra manera. ¡Gracias de cualquier manera! – sippa

1

También puede poner this.hide = true en el evento form_shown. Creo que ese evento se dispara solo una vez y después del evento de carga. Sin embargo, es posible que vea un poco de parpadeo si su formulario tiene muchos controles y/o la computadora está lenta.

+0

Acabo de probar esto, y mientras funciona todavía puede ver el formulario parpadeando muy rápido. Prefiero arreglarlo totalmente, ¡pero gracias por tu sugerencia! – sippa

1

Si su programa no requiere un formulario para ejecutarse, entonces el mejor método es no tener un formulario en absoluto. Configure su NotifyIcon en el código del Programa e ingrese un bucle hasta que desee salir del programa configurando algún valor o llamando a algún método. En este ejemplo, establecer UserExitCalled en true (Program.UserExitCalled = true) hará que el programa se cierre. Aquí está un breve ejemplo:

static class Program { 
    internal static Boolean UserExitCalled; 

    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     // Setup your tray icon here 

     while (!UserExitCalled) { 
      Application.DoEvents(); // Process windows messages 
      Thread.Sleep(1); 
     } 

     return; 
    } 
} 

Aquí la clase de programa completa de una de mis aplicaciones de bandeja de sistema como un ejemplo de trabajo.

// ********************************************************************* 
// [DCOM Productions .NET] 
// [DPDN], [Visual Studio Launcher] 
// 
// THIS FILE IS PROVIDED "AS-IS" WITHOUT ANY WARRANTY OF ANY KIND. ANY 
// MODIFICATIONS TO THIS FILE IN ANY WAY ARE YOUR SOLE RESPONSIBILITY. 
// 
// [Copyright (C) DCOM Productions .NET All rights reserved.] 
// ********************************************************************* 

namespace VisualStudioLauncher 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Windows.Forms; 
    using System.Threading; 
    using VisualStudioLauncher.Common.Objects; 
    using VisualStudioLauncher.Forms; 
    using System.Drawing; 
    using VisualStudioLauncher.Common.Data; 
    using System.IO; 
static class Program 
{ 
    #region Properties 

    private static ProjectLocationList m_ProjectLocationList; 
    /// <summary> 
    /// Gets or Sets the ProjectsLocationList 
    /// </summary> 
    public static ProjectLocationList ProjectLocationList 
    { 
     get 
     { 
      return m_ProjectLocationList; 
     } 

     set 
     { 
      m_ProjectLocationList = value; 
     } 
    } 

    private static ShellProcessList m_ShellProcessList = null; 
    /// <summary> 
    /// Gets or Sets the ShellProcessList 
    /// </summary> 
    public static ShellProcessList ShellProcessList 
    { 
     get 
     { 
      return m_ShellProcessList; 
     } 

     set 
     { 
      m_ShellProcessList = value; 
     } 
    } 

    private static NotifyIcon m_TrayIcon; 
    /// <summary> 
    /// Gets the programs tray application. 
    /// </summary> 
    public static NotifyIcon TrayIcon 
    { 
     get 
     { 
      return m_TrayIcon; 
     } 
    } 

    private static bool m_UserExitCalled; 
    /// <summary> 
    /// Gets a value indicating whether the user has called for an Application.Exit 
    /// </summary> 
    public static bool UserExitCalled 
    { 
     get 
     { 
      return m_UserExitCalled; 
     } 

     set 
     { 
      m_UserExitCalled = value; 
     } 
    } 

    // TODO: Finish implementation, then use this for real. 
    private static ApplicationConfiguration m_ApplicationConfiguration = null; 
    /// <summary> 
    /// Gets the application configuration 
    /// </summary> 
    public static ApplicationConfiguration ApplicationConfiguration 
    { 
     get 
     { 
      if (m_ApplicationConfiguration == null) 
       m_ApplicationConfiguration = ApplicationConfiguration.LoadConfigSection(@"./settings.config"); 

      return m_ApplicationConfiguration; 
     } 
    } 


    #endregion 

    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main(string[] args) 
    { 
     if (args.Length > 0) 
     { 
      if (args[0].ToLower() == "-rmvptr") 
      { 
       for (int i = 1; i < args.Length; i++) { 
        try { 
         if (File.Exists(Application.StartupPath + @"\\" + args[i])) { 
          File.Delete(Application.StartupPath + @"\\" + args[i]); 
         } 
        } 
        catch { /* this isn't critical, just convenient */ } 
       } 
      } 
     } 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     SplashForm splashForm = new SplashForm(); 
     splashForm.Show(); 

     while (!UserExitCalled) 
     { 
      Application.DoEvents(); 
      Thread.Sleep(1); 
     } 

     if (m_TrayIcon != null) 
     { 
      m_TrayIcon.Icon = null; 
      m_TrayIcon.Visible = false; 
      m_TrayIcon.Dispose(); 

      GC.Collect(); 
     } 
    } 

    #region System Tray Management 

    public static void SetupTrayIcon() 
    { 
     m_TrayIcon = new NotifyIcon(); 
     m_TrayIcon.Text = Resources.UserInterfaceStrings.ApplicationName; 
     m_TrayIcon.Visible = false; // This will be set visible when the context menu is generated 
     m_TrayIcon.MouseDoubleClick += new MouseEventHandler(m_TrayIcon_MouseDoubleClick); 

     if (Orcas.IsInstalled) 
     { 
      m_TrayIcon.Icon = Orcas.Icon; 
     } 
     else if (Whidbey.IsInstalled) { 
      m_TrayIcon.Icon = Whidbey.Icon; 
     } 
     else { 
      m_TrayIcon.Icon = SystemIcons.Warning; 
      m_TrayIcon.Text = "Visual Studio is not installed. VSL cannot run properly."; 
     } 
    } 

    static void m_TrayIcon_MouseDoubleClick(object sender, MouseEventArgs e) 
    { 
     if (e.Button != MouseButtons.Left) 
     { 
      return; 
     } 

     SettingsForm settingsForm = new SettingsForm(); 
     settingsForm.Show(); 
    } 

    #endregion 
} 

}

+0

A menos que llame a Application.Run, no creo que se inicie el bucle de mensaje/bomba. – VBNight

+0

Puede procesar mensajes llamando a Application.DoEvents(). Como este no es un escenario complejo, ni siquiera necesita declarar un formulario, solo ejecuta el bucle de mensaje utilizando Application.Run() "Si no lo necesita en su código, elimínelo". Especialmente en el código de producción. –

1

lo he hecho sólo cambiar esta propiedad: Application.OpenForms["Form1"].Opacity = 0;

Cuestiones relacionadas