• Welcome to TechPowerUp Forums, Guest! Please check out our forum guidelines for info related to our community.

Snippet C#: Hiding a form within the form constructor.

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.63/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
I ran into a little nucience of .NET today: hiding a form from within a form. It should be really simple like this:

Code:
public Main()
{
        InitializeComponent();
        this.Hide();
}
You'd think it would work, but it doesn't. Handles (which .Hide() uses) don't work until the form leaves the constructor.

So, how to work around this? Make a second thread to order the form to hide itself, of course! Here's the important code:

Code:
public delegate void AutomaticHideHandler(); // This is what we trigger and place on the event stack.

public class Main : Form
{
    public event AutomaticHideHandler AutomaticHide; // This holds all triggered events.
    private Thread _AutoHide = null; // This makes sure the thread is alive (in the memory) as long as we need it.

    public Main()
    {
        AutomaticHide += new AutomaticHideHandler(Main_AutomaticHide); // Add an instance of the of the event to the event stack.

        InitializeComponent();  // This initializes the form.

        _AutoHide = new Thread(Main_AutomaticHide);  // This creates a new thread and saves it into our class variable.
        _AutoHide.Start();  // This starts the thread we just created.
    }

    private void Main_AutomaticHide()
    {
        // Because another thread is going to call this method, we have to catch the cross-threaded reference before it happens.
        if (this.InvokeRequired)
        {
            this.Invoke(new AutomaticHideHandler(AutomaticHide)); // Make the form's thread retrigger the event
            _AutoHide = null; // Free up the memory from _AutoHide which is no longer needed.
        }
        else
            this.Hide();  // Finally hide the form.
    }
}

Basically, all the above code does is create a "helper" thread which tells our form thread that it needs to hide. The form thread won't allow this so we have to make the form thread tell itself it needs to hide.

This isn't as good as not creating the form in the first place but it is a quick fix. You will see the form blash for less than a second before it hides.


If you want more information about how this works, do some searching on multi-threaded programming in C#. This trick can also be done in VB.NET.


Note: This method does not appear to work in Server 2003.
 
Last edited:

Braveheart

New Member
Joined
Mar 26, 2008
Messages
1,115 (0.19/day)
System Name mystie
Processor intel Q9450
Motherboard gigabyte EP45 UD3P
Cooling coolit domino ALC
Memory 4GB DDR3 1333
Video Card(s) sapphire 4870x2
Storage 250GB barracuda, 1.5TB barracuda
Display(s) 15" phillips, HannsG HD 28"
Case custom built plexiglass cube
Audio Device(s) Creative audigy SE
Power Supply Silverstone Strider 700W
Software Vista home premium 64/ Ubuntu 10.04 Beta 64
have you tried the this.hide() in C# 4.0?
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.63/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
Nope, did they fix it?

I'm running Visual Studio .NET 2008 with .NET Framework 2.0 on that app.
 

Kreij

Senior Monkey Moderator
Joined
Feb 6, 2007
Messages
13,817 (2.20/day)
Location
Cheeseland (Wisconsin, USA)
Just out of curiosity, why do you want to hide the main form in its constructor?
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
26,259 (4.63/day)
Location
IA, USA
System Name BY-2021
Processor AMD Ryzen 7 5800X (65w eco profile)
Motherboard MSI B550 Gaming Plus
Cooling Scythe Mugen (rev 5)
Memory 2 x Kingston HyperX DDR4-3200 32 GiB
Video Card(s) AMD Radeon RX 7900 XT
Storage Samsung 980 Pro, Seagate Exos X20 TB 7200 RPM
Display(s) Nixeus NX-EDG274K (3840x2160@144 DP) + Samsung SyncMaster 906BW (1440x900@60 HDMI-DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay + USB 3.2 (A+C) 3.5" bay
Audio Device(s) Realtek ALC1150, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse Nixeus REVEL-X
Keyboard Tesoro Excalibur
Software Windows 10 Home 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
Primarily because the application was made over a year ago (closer to two years) and is rather extensive. I've been making small improvements to it throughout that period and it is now at version 0.25.0.# (25 major feature changes since original build).

The app creates the form, the form creates the notify icon, and once that notify icon is created, I no longer need to be able to see the form. Instead of having to click somewhere to hide it every time the app starts, I wanted to make it a setting the application could apply.

In order to move the notify icon code out of the Main form I would have had to recode half the GUI. So I had to choose between recoding half of the GUI, use a second thread to hide it, or do nothing at all. Since Server 2003 is where I use this application, the second option is useless. The first option is more work than I care to commit to right now so, I ultimately took the third route and removed all code.

If I were to primarily run it in Windows XP, I would have left it. It does work as a quick fix to a deeper problem but apparently it doesn't work on all platforms. Maybe someone will find it useful (it almost was to me).


Its getting to the point where I need to recode it from scratch. I want to make the options a PropertyGrid, add more features to the timeline (like the ability to make one event relative to another), add more optional settings, make the tray icon separate from all other GUIs, change the GUI, clean up the code, and maybe get creative with the tray icon (have it show lunar and day/night cycles). Time is of the essence and all those features have actual little practical use for me.
 
Last edited:
Top