С#: отображение невидимой формы

У меня есть следующий код в С#:

Form f = new MyForm();
f.Visible = false;
f.Show();
f.Close();

Несмотря на f.Visible = false, я вижу вспышку формы, которая появляется, а затем исчезает. Что мне нужно сделать, чтобы сделать эту форму невидимой?

Мне нужно показать форму (невидимо) во время всплеска моего приложения, потому что это удаляет задержку холодного запуска при показе этой формы.

Ответ 1

Если вы хотите показать форму, не видя ее, вы можете сделать это:

  public Form1()
  {
     InitializeComponent();
     this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
     this.ShowInTaskbar = false;
     this.Load += new EventHandler(Form1_Load);
  }

  void Form1_Load(object sender, EventArgs e)
  {
     this.Size = new Size(0, 0);
  }

Если позже вы хотите его показать, вы можете просто изменить все. Вот пример через 10 секунд, он показывает форму:

  Timer tmr = new Timer();
  public Form1()
  {
     tmr.Interval = 10000;
     tmr.Tick += new EventHandler(tmr_Tick);
     tmr.Start();

     InitializeComponent();
     this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
     this.ShowInTaskbar = false;
     this.Load += new EventHandler(Form1_Load);
  }

  void tmr_Tick(object sender, EventArgs e)
  {
     this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable;
     this.ShowInTaskbar = true;
     this.Size = new Size(300, 300);
  }

  void Form1_Load(object sender, EventArgs e)
  {
     this.Size = new Size(0, 0);
  }

Ответ 2

Безусловно, самый простой способ сохранить невидимую форму - это просто не показывать ее. Это очень важно в Winforms, вызывая Show() или устанавливая свойство Visible true (то же самое), делает много вещей. Это способ создания собственного окна Windows. В типичной .NET "ленивой" моде. Любая попытка установить видимость обратно на false (например, в OnLoad) будет побеждена.

Технически это возможно, вам нужно переопределить метод SetVisibleCore(). Вот так:

    protected override void SetVisibleCore(bool value) {
        if (!this.IsHandleCreated) {
            this.CreateHandle();
            value = false;   // Prevent window from becoming visible
        }
        base.SetVisibleCore(value);
    }

Это гарантирует, что окно не станет видимым при первом вызове Show(). Это удобно, если у вас есть NotifyIcon, например, вы обычно хотите, чтобы значок находился непосредственно в области уведомлений и отображал только окно, когда пользователь нажимает на значок. Помните, что OnLoad() не запускается до тех пор, пока окно не станет видимым, поэтому при необходимости переместите код в конструктор или переопределите.

Ответ 3

Просто потому, что f.Show() делает форму Visible снова, а f.Close() закрывает ее... так что flash.

Если вы видите документ MSDN для метода Form.Show(), он ясно указывает, что:

Отображение элемента управления эквивалентно для установки свойства Видимое: true. После вызова метода Show свойство Visible возвращает значение true до тех пор, пока не будет вызван метод Hide.

<ч/" > Если вы не хотите, чтобы вспышка просто не отображала форму вообще.

Ответ 4

Вам нужно отредактировать класс MyForm и добавить следующий метод переопределения:

protected override void SetVisibleCore(bool value)
{
    //just override here, make sure that the form will never become visible
    if (!IsHandleCreated) CreateHandle();
    value = false;
    base.SetVisibleCore(value);
}

Вы должны спросить себя, действительно ли это действительно необходимо - вероятно, это указывает на плохой дизайн.

Edit: Довольно редко, что вам нужно это сделать, единственная ситуация, которую я использовал, - это когда мне нужна форма, на которой я могу разместить COM-компонент (поскольку COM-компоненту нужен дескриптор Window), и мне пришлось запустить Application.Run(formInstance), который вызывает метод Show формы. Заставляя форму всегда быть невидимой, вы получаете дескриптор окна и цикл сообщений, не видя ничего на экране.

Ответ 5

Я создал вспомогательный метод, который будет показывать невидимую форму, а последующие вызовы Show будут отображаться как обычно:

public static class FormHelper
{
    public static void ShowInvisible(this Form form)
    {
        // saving original settings
        bool needToShowInTaskbar = form.ShowInTaskbar;
        WindowState initialWindowState = form.WindowState;

        // making form invisible
        form.ShowInTaskbar = false;
        form.WindowState = FormWindowState.Minimized;

        // showing and hiding form
        form.Show();
        form.Hide();

        // restoring original settings
        form.ShowInTaskbar = needToShowInTaskbar;
        form.WindowState = initialWindowState;
    }
}

Таким образом, форма будет отображаться (и событие Load будет срабатывать) без каких-либо мерцаний.