• We've upgraded our forums. Please post any issues/requests in this thread.

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

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
20,902 (6.25/day)
Likes
9,994
Location
IA, USA
System Name BY-2015
Processor Intel Core i7-6700K (4 x 4.00 GHz) w/ HT and Turbo on
Motherboard MSI Z170A GAMING M7
Cooling Scythe Kotetsu
Memory 2 x Kingston HyperX DDR4-2133 8 GiB
Video Card(s) PowerColor PCS+ 390 8 GiB DVI + HDMI
Storage Crucial MX300 275 GB, Seagate 6 TB 7200 RPM
Display(s) Samsung SyncMaster T240 24" LCD (1920x1200 HDMI) + Samsung SyncMaster 906BW 19" LCD (1440x900 DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay
Audio Device(s) Realtek Onboard, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse SteelSeries Sensei RAW
Keyboard Tesoro Excalibur
Software Windows 10 Pro 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
#1
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:
Joined
Mar 26, 2008
Messages
1,115 (0.31/day)
Likes
46
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
#2
have you tried the this.hide() in C# 4.0?
 

FordGT90Concept

"I go fast!1!11!1!"
Joined
Oct 13, 2008
Messages
20,902 (6.25/day)
Likes
9,994
Location
IA, USA
System Name BY-2015
Processor Intel Core i7-6700K (4 x 4.00 GHz) w/ HT and Turbo on
Motherboard MSI Z170A GAMING M7
Cooling Scythe Kotetsu
Memory 2 x Kingston HyperX DDR4-2133 8 GiB
Video Card(s) PowerColor PCS+ 390 8 GiB DVI + HDMI
Storage Crucial MX300 275 GB, Seagate 6 TB 7200 RPM
Display(s) Samsung SyncMaster T240 24" LCD (1920x1200 HDMI) + Samsung SyncMaster 906BW 19" LCD (1440x900 DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay
Audio Device(s) Realtek Onboard, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse SteelSeries Sensei RAW
Keyboard Tesoro Excalibur
Software Windows 10 Pro 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
#3
Nope, did they fix it?

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

Kreij

Senior Monkey Moderator
Staff member
Joined
Feb 6, 2007
Messages
13,817 (3.49/day)
Likes
5,524
Location
Cheeseland (Wisconsin, USA)
Processor Intel Core 2 Quad QX9650 Extreme @ 3.0 GHz
Motherboard Asus Rampage Formula
Cooling ZeroTherm Nirvana NV120 Premium
Memory 8GB (4 x 2GB) Corsair Dominator PC2-8500
Video Card(s) 2 x Sapphire Radeon HD6970
Storage 2 x Seagate Barracuda 320GB in RAID 0
Display(s) Dell 3007WFP 30" LCD (2560 x 1600)
Case Thermaltake Armor w/ 250mm Side Fan
Audio Device(s) SupremeFX 8ch Audio
Power Supply Thermaltake Toughpower 750W Modular
Software Win8 Pro x64 / Cat 12.10
#4
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
20,902 (6.25/day)
Likes
9,994
Location
IA, USA
System Name BY-2015
Processor Intel Core i7-6700K (4 x 4.00 GHz) w/ HT and Turbo on
Motherboard MSI Z170A GAMING M7
Cooling Scythe Kotetsu
Memory 2 x Kingston HyperX DDR4-2133 8 GiB
Video Card(s) PowerColor PCS+ 390 8 GiB DVI + HDMI
Storage Crucial MX300 275 GB, Seagate 6 TB 7200 RPM
Display(s) Samsung SyncMaster T240 24" LCD (1920x1200 HDMI) + Samsung SyncMaster 906BW 19" LCD (1440x900 DVI)
Case Coolermaster HAF 932 w/ USB 3.0 5.25" bay
Audio Device(s) Realtek Onboard, Micca OriGen+
Power Supply Enermax Platimax 850w
Mouse SteelSeries Sensei RAW
Keyboard Tesoro Excalibur
Software Windows 10 Pro 64-bit
Benchmark Scores Faster than the tortoise; slower than the hare.
#5
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: