2

I'm creating a System Tray application. Upon initializing the app, I want to:

  • Initialize and load a form so it runs in the background
  • But keep the form hidden (until the user doubleclicks the tray icon)

It is important that the form is loaded and runs in the background, because the form contains an embedded browser that will initialize a web socket connection to receive data. But it needs to be hidden. I tried solving this by playing with the Visible property of the form. So far, I have this (only relevant code shown):

public TrayApp()
{
    var ni = new NotifyIcon();     
    InitializeForm();
    ni.DoubleClick += this.ShowForm;
}

private void InitializeForm()
{
    //load the form in the background so it can start receiving incoming data, but don't actually show the form
    myForm = new MyForm();
    myForm.Show();
    myForm.Visible = false;
}

private void ShowForm(object sender, EventArgs e)
{
    myForm.Visible = true;
}

This works quite well, except for one small detail: upon starting the app, I briefly see the form flashing before it is hidden. I suppose the Show method also sets the Visible flag to true, causing the flash to occur.

Other things I tried, based on comments:

  • Do not call myForm.Show(), only initialize the form. This avoids the flash but won't load the browser and hence the websocket connection is not initialized
  • Do myForm.Hide(): same effect as previous
  • Set Opacity to 0 before calling Show() and set it to 1 after setting Visible to false: this actually works, but I was hoping for a cleaner solution

How to avoid the flash and keep the form running but hidden?

fikkatra
  • 5,605
  • 4
  • 40
  • 66
  • 1
    If you call `Show` or `ShowDialog` it's already too late to hide. Can't you avoid calling those methods instead? Using abstraction where you have model: create model which runs in background, then you can create view at any time (even multiple-views) and attach it to the model to see accumulated or snap-shoot state. Putting socket communications inside `Form` feels so wrong after a bit of MVVM. – Sinatr Jun 13 '16 at 11:24
  • try myform.Hide(); – sowjanya attaluri Jun 13 '16 at 11:28
  • in your initializeform, just dont do the "show" follow it by hiding it, it already exists once youve done new MyForm().. unless you have some triggering code int the show - which you can run.. without showing the form of course – BugFinder Jun 13 '16 at 11:29
  • Maybe I wasn't really clear on the socket stuff. So let me clarify this: the only thing the form contains, is an embedded CEF browser. It is the page running within that browser, that has the websocket connection. The form itself doesn't do anything besides hosting the browser Therefore, it is important that the form remains opened, otherwise, the browser and thus the websocket connection will be killed. Using Hide() will close the form and kill the connection. – fikkatra Jun 13 '16 at 11:31
  • @sowjanya attaluri: just tried your suggestion and doing just myForm.Hide(): this removes the flash, however, the form is not running in the background. It only starts running when I open it by double clicking the tray icon, which is too late. – fikkatra Jun 13 '16 at 11:35
  • 1
    If you are up to a dirty tricks (assuming what you must create handle for something to work? I don't know about `WebBrowser`), then do following: set form size to smallest value possible, show form, hide it, set size to normal, show normally. Also see [this](http://stackoverflow.com/q/1952687/1997232). – Sinatr Jun 13 '16 at 11:36
  • can't you give it a Top and Left that moves it out of the way? Both values on -10000? – rene Jun 13 '16 at 11:39
  • You can get the idea from http://stackoverflow.com/questions/510765/c-sharp-winforms-startup-splash-form-not-hiding/510786#510786 – mohsen Jun 13 '16 at 11:42
  • @BugFinder if I don't call Show(), the browser is not loaded and hence the websocket is not initialized, which results in my app not retrieving any data. – fikkatra Jun 13 '16 at 11:59

2 Answers2

0

You could try to set the hide property before you show your form.

myForm = new MyForm();
myForm.Visible = false;
myForm.Show();
0

You could try to write a function that initializes the socket. Put this function inside your MyForm class and call it from inside the InitializeForm().

Hope this helps.

  • The socket is initialized from the website that is running within the browser (hosted by the form). There's no need to create a socket connection from within the form application. I seem to have confused everybody by mentioning the word 'socket', but I just wanted to emphasize that it's important that the browser within the form is actually running (e.g. the form is loaded). – fikkatra Jun 13 '16 at 14:29