views:

62

answers:

3

I would like someone to try and explain the difference between these. More specifically, example usage scenario's.

I am refactoring some Windows Form code and a Form has some code in the Form_Load() event and also in a protected override void OnLoad() event that calls base.OnLoad(e); Now I traced it and the Override fires first and then immediately fires off the event version.

So, which one is typically used and why?

Thanks,

+1  A: 

OnLoad raises the Load event, which Form_Load handles. See the MSDN article.

So, in your code, at the end of your initialization function, you could call the OnLoad function. The base class will then call your event handlers (Form_Load in this case), which you may have set in your initialization code.

Personally, I would place my code in the Form_Init and leave OnLoad for initiating the event, since I'm handling the event, although you can defend either with good reason, as you see from your answers.

palswim
I may be dense but I think you are confirming what I said about OnLoad calling the Load Event but does this answer my question about which one I should be placing my code in? It seems, to me, that I can put it in either with equal effect as long as it is after the `base.OnLoad(e)` call.
Refracted Paladin
+1  A: 

The base.OnLoad method invokes the Load-event of the Form.

protected override void OnLoad(EventArgs e)
{
  // do stuff before Load-event is raised
  base.OnLoad(e);
  // do stuff after Load-event is raised
}

If you don't specifically need to perform stuff before the Load-event is raised, placing the code in OnLoad after base.OnLoad(e) is as good as placing it in the Form_Load event handler.

Bernhof
Thanks for the response but it sounds like you are saying there isn't a definitive answer to my question beyond timing of the Form Loading, correct?
Refracted Paladin
I would personally override the OnLoad method, since this is the typical approach when creating inherited classes. The events are, as mentioned by Hans Passant, meant for other classes who can subscribe to these. But in practice there is no real difference.
Bernhof
Thanks, that makes sense
Refracted Paladin
+5  A: 

You should always override OnLoad(). Using the event is only appropriate when another class would be interested in the event. Which is what events are for. Another class being interested in the Load event is very rare, only really useful to do window arrangement stuff.

Still, the Load event works well with the designer and VB6 programmers are very comfortable with it. It isn't horribly wrong, you'd only get in trouble when you start inheriting the form and code doesn't run in the right order.

Most code that now gets put in the Load event really belongs in the constructor. You only need OnLoad if:

  • You need to know the exact size and position of the window. OnLoad is best, the window Handle is created and the user preferences are applied (title and border size) and the form was rescaled as directed by the Form.AutoScaleMode property. The window is not yet visible, a very good time to move the window somewhere else or to arrange the child controls.
  • You have code that needs the Handle property. This is subtle, you cannot always tell. Having code like that in the constructor is unhealthy, the window gets created before the constructor completed. It usually comes to a good end but it can make creating the form very slow. Easy to diagnose from the Call Stack window.
  • To avoid a bug in the MDI implementation. If you create an MDI child in the parent constructor then you'll get duplicated glyphs, visible when you maximize the child. Create the child in OnLoad instead.
Hans Passant
So, stop me if I am wrong, but it is more "correct" to use the `OnLoad()` but I would need to be cognizant of the fact that the code in there would not be available to another class. Correct?
Refracted Paladin
It *is* available to a derived class, base.OnLoad(). Skipping the initialization of the base class would almost always be wrong. *Another* class has no business with the code in Load/OnLoad.
Hans Passant
So if a derived class call `OnLoad()` it would fire `base.OnLoad()` and then any code I put after that.
Refracted Paladin
A derived class never calls OnLoad, that's goes kaboom. Always base.OnLoad().
Hans Passant
Can I sum up your answer as use `OnLoad()` except when explicitly needed otherwise.
Refracted Paladin
+1, nice answer. Related: where would you put cleanup code (like deregistering even handlers)? Overriding OnFormClosed?
snemarch
@sne - yes, same logic applies.
Hans Passant
@Hans Passant: well, I was wondering whether you'd suggest something else (overriding Dispose?) since you suggest putting other initialization in the constructor rather than overriding OnLoad :)
snemarch
@sne - a good answer doesn't fit in a comment box. I recommend you start your own thread.
Hans Passant