1

So i am relearning C# and the .net framework again after a couple years of using other languages and i have a "best practice" question i hope someone can answer.

Looking at the below code for a new form entitled "Choose_File", i have been putting my "on load" code right after the

InitializeComponent();

line because for some reason i thought that was the "on load" method. After creating a couple forms using this method, i accidentally double clicked the header of the form and it opened the real "_Load" method where i am assuming i should have been putting the "on load" code all along. So my question is what is the actual real world difference between these two methods from a practical sense since both seem to work?

namespace Personal_Finance_Manager
{
    public partial class Choose_File : Form
    {
        public Choose_File()
        {
            InitializeComponent();
        }

        private void Choose_File_Load(object sender, EventArgs e)
        {

        }
    }
}
BenW301
  • 352
  • 2
  • 3
  • 18
  • 2
    http://stackoverflow.com/questions/13860609/load-onload-constructor – markhc Jan 21 '15 at 05:22
  • So based on the above article it seems like i was correct by placing the code in the constructor rather than the on-load? Is this because the constructor is run when the form is initialized and thus anything that affects how the form is going to display should be run at that point vs changing it after the form has already been displayed as would happen when that code was placed in the on-load? – BenW301 Jan 21 '15 at 05:25
  • IMO it's personal preference. I like to only initialize variables that the form needs on the constructor and if I have to set the text of TextBox, label, etc for example, I'll do it on the OnLoad. – markhc Jan 21 '15 at 05:27
  • Is there a specific reason for that? At this point I'm not attached to either route so from a "starting good habits" point of view, why is setting text done after? – BenW301 Jan 21 '15 at 05:30
  • 1
    For me, not really. Personal habit. You could also override the OnLoad event as I see people do sometimes. I dont think any single alternative is *that* much better compared to the others. – markhc Jan 21 '15 at 05:34
  • 1
    In practice, the form will not actually be drawn yet when `OnLoad()` is called. So you could defer initialization to this point without the user noticing. However, everything will have default values, and so arguably there is a minor extra overhead if you delay customized initialization to that point, because the various native data structures will already have to have been initialized to default values too (i.e. they get initialized twice). Thus it's my preference to always initialize as much as early as possible. I only use `Load` and `Shown` for things that simply cannot be done earlier. – Peter Duniho Jan 21 '15 at 05:35

2 Answers2

1

OnLoad event is fired when the form is Shown (Form.Show() was called). The constructor is called whenever a new instance of the Form is created, even if it was not yet displayed.

Code that should be execute only when the form is shown to the user (i.e. instantiate class members) goes on the OnLoad handler, code that needs to be executed before the form is shown goes on the constructor.

markhc
  • 659
  • 6
  • 15
  • 3
    Note that `OnLoad()`, `Load` event, and `Shown` are called/raise only the _first_ time that a form is shown. If, for example, you set `Visible = false;` and then `Visible = true;` again later, or alternatively call `Hide()` and then `Show()` again later, you don't get another `Shown` event. See [Form.Shown Event](https://msdn.microsoft.com/en-us/library/system.windows.forms.form.shown(v=vs.110).aspx) and [Order of Events in Windows Forms](https://msdn.microsoft.com/en-us/library/86faxx0d(v=vs.110).aspx) – Peter Duniho Jan 21 '15 at 05:31
1

You should initialize class elements as early as practical. For most things, that will be in the constructor. You can initialize control properties, class fields, etc. here and it will work fine.

However, there are some things you cannot do with a Control instance (including a Form subclass) until the underlying native window handle has been created. For these types of initialization, overriding OnLoad() (or handling the Load event) and performing that initialization (only) is appropriate.

As an example, when I am showing a form to display progress for a background task, I will handle the Shown or Load event (for this purpose, they are equivalent) and not start the background task until then. This ensures against the background task finishing so quickly that the form hasn't even been fully initialized by the time it's done, which would prevent the post-task code from closing the form (you can't close a form that hasn't been opened yet :) ).

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • So if i understand you correctly, all my "this is the initial state of the form" code should go in the constructor and all the "these are the things that can change or alter the base state" go in the on load to prevent them from firing before the initial form is loaded? – BenW301 Jan 21 '15 at 05:33
  • 1
    I'm not sure what you mean by "base state", but I think no, that's not what I'm saying. Forms have all kinds of state, even state that is also initialized in the constructor, that may change while the user interacts with it, and that's fine. But of all the stuff that falls into "initialization" (i.e. setting the _initial_ values for the form), I do that as early as possible, to minimize duplicated effort in the object. If something comes up that simply cannot be done safely in the constructor, then I defer it to `OnLoad()` or equivalent. – Peter Duniho Jan 21 '15 at 05:38