2009-02-06 6 views
10

У меня есть программа, которая нуждается только в NotifyIcon для работы по назначению. Поэтому я пытаюсь скрыть основную форму при запуске программы.Скрыть форму при запуске

В frmMain_Load, я попытался как

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

без успеха.

Они работают другими способами, например, в методе NotifyIcon_MouseClick, но я хочу, чтобы он спрятался при загрузке.

я видел другой вопрос здесь SO, где Матиас предложил это:

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

Это работает, но когда я запускаю программу, которую я могу видеть форму мигающей очень быстро. Это лучше, чем ничего, но мне интересно, есть ли лучшее решение для этого.

Спасибо.

ответ

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

Это решение имеет проблемы. В этом случае, когда вы закрываете форму, события FormClose и FormClosing не будут повышены. – parseh

+0

Как вы можете закрыть приложение, когда форма закрыта с помощью кнопки X? –

+0

Лучшим решением является создание «ApplicationContext» и передача его экземпляра в «Application.Run()», который управляет жизненным циклом формы, тем самым избегая необходимости вызывать 'Application.Exit()' в другом месте. –

2

Не вызывайте Show или ShowDialog в своей форме, вы можете иметь свой Application.Run целевой пользовательский класс, который затем создает экземпляр формы и не показывает или не создает экземпляр NotifyIcon и обрабатывает все оттуда.

+0

Вы также можете просто позвонить Application.Run() без каких-либо параметров. Когда ваше приложение завершено, вызовите приложение.Выход(); – VBNight

+0

Это не сработает, если вам нужно получить уведомления о событиях, например, силовые события и т. Д., Где вам действительно нужна (невидимая) форма для их получения. –

+0

Спасибо за ваш ответ. Должен ли я создать собственный собственный класс формы или я могу просто удалить Show() - строку где-нибудь? Если мне нужно создать собственный пользовательский класс, как мне это сделать? Я искал код, но я не нашел ничего интересного. – sippa

5

Существует простой способ, если ваша программа имеет по умолчанию Visual Studio сгенерированный Program.cs файл:

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

простой факт вызова Run будет, на самом деле сделать форму видимой. Попробуйте сделать следующее в свойствах вашей формы:

  1. Установите WindowState в Minimized
  2. Установите ShowInTaskbar в false

Это должно сделать трюк!

+0

Спасибо за ваш ответ! Я забыл упомянуть, что я уже пробовал этот путь. Он работал частично, но я мог видеть строку заголовка формы в левом нижнем углу, поэтому я хочу сделать это по-другому. Спасибо, в любом случае! – sippa

1

Вы также можете поместить this.hide = true в событие form_shown. Я считаю, что событие запускается только один раз и после события загрузки. Возможно, вы видите мерцание, хотя в вашей форме есть много элементов управления и/или компьютер работает медленно.

+0

Я просто попробовал это, и пока он работает, вы все равно можете видеть, что форма быстро мигает. Я предпочел бы исправить это, но спасибо за ваше предложение! – sippa

1

Если ваша программа не требует формы для запуска, то лучшим способом является отсутствие формы. Настройте свой NotifyIcon в программном коде и введите цикл, пока вы не захотите выйти из программы, установив какое-то значение или вызов какой-либо метод. В этом примере установка UserExitCalled на true (Program.UserExitCalled = true) приведет к завершению работы программы. Вот краткий пример:

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

Здесь полный класс программы из одного из приложений моей панели задач в качестве рабочего примера.

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

Если вы не вызвали Application.Run, я не думаю, что цикл сообщений/насос начнется. – VBNight

+0

Вы можете обрабатывать сообщения, вызывая Application.DoEvents(). Так как это не сложный сценарий, ему не нужно даже объявлять форму, но в одиночку запускать цикл сообщений, используя Application.Run() «Если вам это не нужно в коде, удалите его». Особенно в производственном кодексе. –

1

Я сделал это только изменение этого свойства: Application.OpenForms["Form1"].Opacity = 0;

Смежные вопросы