1

I have a System.Windows.Forms.Form window, that needs to get events delivered to it with Control.Invoke(). However, the messages are not getting delivered prior to calling Show() on the form.

In order to work around this, I tried this kludge in the form's constructor:

this.Show();
this.Hide();

This works, and the messages are now getting delivered. However, this results in a window flashing in and out when the form is constructed. Is there a more elegant way to achieve what I want?

I'm working with .NET 2.0 (a newer version is not allowed).

Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
Nikos C.
  • 50,738
  • 9
  • 71
  • 96
  • 1
    Yuck, in 2.0 id be happy i found an answer. Play around with suspend layout or suspend draw. http://msdn.microsoft.com/en-us/library/system.windows.forms.control.suspendlayout(v=vs.110).aspx – DidIReallyWriteThat Aug 29 '14 at 12:27
  • `this.CreateControl()` or calling `this.Handle` would do that I guess. – Sriram Sakthivel Aug 29 '14 at 12:28
  • Possible hack: Before calling Show/Hide, temporarily set the top/left coordinates to something negative, moving the form off the display surface. – 500 - Internal Server Error Aug 29 '14 at 12:29
  • May I ask what you're trying to achieve? You may get better answer in that case. – Sriram Sakthivel Aug 29 '14 at 12:32
  • @SriramSakthivel It's a window that needs to stay hidden unless there's reason to show it. The window manages that stuff all by itself and it's part of a class library. All the user of that library needs to do is instantiate it, and when something interesting happens, the window shows itself. The window knows whether something interesting happened or not, by subscribing to events of other objects and those events are always delivered with Control.Invoke(). – Nikos C. Aug 29 '14 at 12:38
  • Another "hacK" would be to set the forms opacity to 0 before calling Show(), and then after hiding it, set it back to full opacity. – ForeverZer0 Aug 29 '14 at 12:50
  • You may want to take a look at [this old question of mine](http://stackoverflow.com/questions/2523778/forcing-a-checkbox-bound-to-a-datasource-to-update-when-it-has-not-been-viewed-y) that tries to solve the same problem. – Scott Chamberlain Aug 29 '14 at 13:07
  • @ScottChamberlain Just reading `this.Handle` is way simpler though :-P – Nikos C. Aug 29 '14 at 13:15

1 Answers1

2

Criterion of Control.Invoke is that Handle has to be created and nothing else. You don't need to call Show and Hide instead force creating the Handle.

Form yourForm = new Form();
var handle =  pbForm.Handle;//Force create handle

From this point you can able to call yourForm.Invoke

Note: Your form's Load event and Shown event will not be fired unless you show the form. So any code depends on those events will break.

If your code depends on Load or Shown events, you need a hack. You need to make the form very small so that user can't notice it (Probably size of 1,1), then call Show and Hide. Later at some point when you need to show the form to user you can set a decent Size.

Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • Yep, I tried both CreateControl() as well as reading `this.Handle` (from your original comment.) Only the latter works. I've simply done `var bogus = this.Handle;` in the ctor. Though I'm a bit worried about the optimizer. I assume that the side effects of the `Handle` getter will prevent this from getting optimized out? (Btw, the `Load` and `Shown` events are not important in my case.) – Nikos C. Aug 29 '14 at 12:50
  • @NikosC. Am not expert in this topic. To be on safer side cheat the jit and compiler optimizers by pretending to use the `Handle` somehow. Let's say `Console.WriteLine(this.Handle);` which can't be optimized. – Sriram Sakthivel Aug 29 '14 at 12:53
  • Hm, I guess I'll assign it to a `volatile` member in this case. Too bad `volatile` is not allowed on local vars. – Nikos C. Aug 29 '14 at 12:54