2009-02-06 15 views
10

Ich habe ein Programm, das nur eine NotifyIcon benötigt, um wie beabsichtigt zu arbeiten. Also habe ich versucht, das Hauptformular zu verstecken, wenn das Programm startet.Formular beim Start verstecken

In frmMain_Load habe ich versucht, beide

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

ohne Erfolg.

Sie arbeiten in anderen Methoden, wie in der NotifyIcon_MouseClick-Methode, aber ich möchte es bei Load verstecken.

sah ich hier in einer anderen Frage auf SO, wo Matias dies vorgeschlagen:

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

Dies funktioniert, aber wenn ich das Programm starten kann ich die Form zu blinken wirklich schnell sehen. Es ist besser als nichts, aber ich frage mich, ob es eine bessere Lösung dafür gibt.

Danke.

Antwort

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

Diese Lösung hat ein Problem. In diesem Fall würden beim Schließen des Formulars die Ereignisse "FormClose" und "FormClosing" nicht erhöht. – parseh

+0

Wie können Sie die Anwendung beenden, wenn das Formular mit der Schaltfläche X geschlossen wird? –

+0

Eine bessere Lösung besteht darin, einen 'ApplicationContext' zu erstellen und eine Instanz davon an' Application.Run() 'zu übergeben, die den Lebenszyklus des Formulars verwaltet und somit vermeidet,' Application.Exit() 'an anderer Stelle aufzurufen. –

2

Rufen Sie nicht Show oder ShowDialog auf Ihrem Formular auf, Sie können Ihre Application.Run-Ziel eine benutzerdefinierte Klasse, die dann ein Formular instanziiert und zeigt keine NotifyIcon-Instanz und erstellt alles von dort.

+0

Sie können auch (nur Application.Run nennen) ohne Parameter. Wenn Ihre Anwendung beendet ist, rufen Sie die Anwendung.Ausgang(); – VBNight

+0

Dies funktioniert nicht, wenn Sie einige Ereignisbenachrichtigungen, wie z. B. Energieereignisse, benötigen, in denen Sie wirklich ein (unsichtbares) Formular benötigen, um sie zu erhalten. –

+0

Danke für Ihre Antwort. Muss ich meine eigene benutzerdefinierte Formularklasse erstellen oder kann ich die Show() - Zeile irgendwo entfernen? Wenn ich meine eigene benutzerdefinierte Klasse erstellen muss, wie mache ich das? Ich habe mich im Code umgesehen, aber ich finde nichts Interessantes. – sippa

5

Es ist eine einfache Möglichkeit, wenn Ihr Programm die Standard-Visual Studio Program.cs Datei erzeugt hat:

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

die einfache Tatsache Run des Aufrufs wird, in der Tat die Form sichtbar machen. Versuchen Sie Folgendes in den Eigenschaften des Formulars tun:

  1. Set WindowState zu Minimized
  2. Set ShowInTaskbar zu false

Dies sollte es tun!

+0

Danke für Ihre Antwort! Ich habe vergessen zu erwähnen, dass ich das schon mal versucht habe. Es funktionierte teilweise, aber ich konnte die Form Titelleiste in der unteren linken Ecke sehen, also möchte ich es auf eine andere Weise machen. Danke trotzdem! – sippa

1

Sie können this.hide = true auch im form_shown-Ereignis angeben. Ich glaube, dass Ereignis nur einmal und nach dem Load-Ereignis ausgelöst wird. Sie können jedoch ein wenig Flimmern sehen, wenn Ihr Formular viele Steuerelemente enthält und/oder der Computer langsam ist.

+0

Ich habe gerade versucht, und während es funktioniert, können Sie immer noch die Form blitzschnell blinken sehen. Ich würde es lieber total reparieren, aber danke für deinen Vorschlag! – sippa

1

Wenn Ihr Programm kein Formular zum Ausführen benötigt, dann ist die beste Methode, kein Formular zu haben. Richten Sie Ihre NotifyIcon im Programmcode ein, und geben Sie eine Schleife ein, bis Sie das Programm beenden möchten, indem Sie einen Wert festlegen oder eine Methode aufrufen. In diesem Beispiel bewirkt das Setzen von UserExitCalled auf true (Program.UserExitCalled = true), dass das Programm beendet wird. Hier ein kurzes Beispiel:

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; 
    } 
} 

Hier die vollständige Programmklasse aus einer meiner System-Tray-Anwendungen als Arbeitsbeispiel.

// ********************************************************************* 
// [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

Wenn Sie Application.Run nicht aufrufen, denke ich nicht, dass die Meldung loop/pump gestartet wird. – VBNight

+0

Sie können Nachrichten verarbeiten, indem Sie Application.DoEvents() aufrufen. Da dies kein komplexes Szenario ist, muss er nicht einmal ein Formular deklarieren, aber die Meldeschleife allein mit Application.Run() ausführen. "Wenn Sie es nicht in Ihrem Code benötigen, entfernen Sie es." Vor allem im Produktionscode. –

1

ich es gerade diese Eigenschaft zu ändern getan haben: Application.OpenForms["Form1"].Opacity = 0;