Craig Johnston
Craig Johnston

Reputation: 7607

C#: showing an invisible form

I have the following code in C#:

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

Despite the f.Visible = false, I am seeing a flash of the form appearing and then disappearing. What do I need to do to make this form invisible?

I need to show the form (invisibly) during the splash of my app because doing this removes a cold start delay when showing this form.

Upvotes: 18

Views: 17958

Answers (5)

Vadim Ovchinnikov
Vadim Ovchinnikov

Reputation: 14012

I've created helper method that will to show invisible form and subsequent Show calls will show window as usually:

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

So form will be rendered (and Load event will trigger) without any blink.

Upvotes: 0

SwDevMan81
SwDevMan81

Reputation: 49978

If you want to show the form without actually seeing it, you can do this:

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

If at a later point you want to show it, you can just change everything back. Here is an example after 10 seconds, it shows the form:

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

Upvotes: 19

Alistair Evans
Alistair Evans

Reputation: 36473

You need to edit the MyForm class, and add the following override method:

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

You should ask yourself if this is really necessary however - probably indicative of poor design really.

Edit: It's pretty rare that you need to do this, the only situation I've used it is when I needed a form I could place a COM component on (since the COM component needed a Window handle), and I had to run Application.Run(formInstance) which calls the Show method of the form. By forcing the form to always be invisible, you get a window handle and a message loop without seeing anything on screen.

Upvotes: 4

Hans Passant
Hans Passant

Reputation: 941218

By far the simplest way to keep a form invisible is just by not showing it. It is a big deal in Winforms, calling Show() or setting the Visible property to true (same thing) does a lot of things. It is the way the native Windows window gets created. In typical .NET 'lazy' fashion. Any attempt to set Visible back to false (like in OnLoad) will be defeated.

Technically it is possible, you have to override the SetVisibleCore() method. Like this:

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

This ensures that the window doesn't become visible the first time you call Show(). Which is handy when you have NotifyIcon for example, you typically want the icon directly in the notification area and only display a window when the user clicks on the icon. Beware that OnLoad() doesn't run until the window actually becomes visible so move code to the constructor or the override if necessary.

Upvotes: 13

Shekhar_Pro
Shekhar_Pro

Reputation: 18420

Simply Because f.Show() is making the form Visible again and f.Close() is Closing it... so the flash.

If you see the MSDN doc for Form.Show() method it clearly mentions that:

Showing the control is equivalent to setting the Visible property to true. After the Show method is called, the Visible property returns a value of true until the Hide method is called.


If you don't want the flash just don't show the Form at all.

Upvotes: 9

Related Questions