Skip navigation.

Code Samples: Inline or Code-Behind?All recent postsMy First Impression of Profile Providers

Minimalist Code-Behind Template

Scott Allen asks: in your code-behind, do you prefer Page_Load or OnLoad? Those who read my article on “remastering” web forms know how uneasy I feel about the template VS.NET dishes out when you create a new web form.

Take Control of Initialization

These days, whenever I create a new form, I skin it to this:

using System;
using System.Web.UI;

namespace Playground
{
  public class WebForm1 : Page
  {
     override protected void OnInit(EventArgs e)
     {
        base.OnInit(e);
      }
   }
}

I have a good reason to remove InitializeComponent (see default template) and move event wires-ups into OnInit. The culprit here is VS.NET. Suppose you have a couple of controls with their events wired in InitializeComponent:

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{ 
  this.Button1.Click += new System.EventHandler(this.Button1_Click);
  this.List1.SelectedIndexChanged += 
       new System.EventHandler(this.List1_SelectedIndexChanged);
  this.Load += new System.EventHandler(this.Page_Load);
}

I don’t know what happens, but at times, when you remove some control, then add another one, etc, VS.NET quietly gets rid of wired events. The compiler won’t report it, because—technically—it’s not an error, but your controls won’t function. It’s very embarrassing.

Since there hasn’t been a single service pack for VS.NET, I do not trust it. Fool me once—shame on you, fool me twice… Therefore I move event where VS.NET won’t touch them and wipe out InitializeComponent:

override protected void OnInit(EventArgs e)
{
  this.Button1.Click += new System.EventHandler(this.Button1_Click);
  this.List1.SelectedIndexChanged += 
       new System.EventHandler(this.List1_SelectedIndexChanged);
  this.Load += new System.EventHandler(this.Page_Load);

  base.OnInit(e);
}

If you leave page initialization in the hands of VS.NET 2003, you’re playing with fire.

OnLoad or Page_Load?

Scott has described pros and cons of both. To me, the way the template is set up right now is odd. You override Page.OnInit, but wire an event handler for Page.Load and end up with different method signatures. The Control class also has a PreRender event, but we’re always taught to override OnPreRender. All OnXxxx methods do is call wired handlers of their respective events. There’s not much more to it.

For the sake of consistency I choose to override OnXxxx methods. It’s only a matter of personal preference.

Do You Wire Events in HTML Designer or Code-Behind?

Suppose you have a simple Button control. You learn from books to set up its Click handler right in the HTML designer:

<asp:button id="Button1" Runat="server" OnClick="xxxx" />

Again, it’s a matter of personal likes and dislikes, but in my book doing so is impractical. These definitions are hard to maintain, and you do not get compile-time error resolution should you type something wrong. Another issue with this—VS.NET again. It shuffles attributes back and forth without warning, so control declaration is not guaranteed to stay the same. Do it at your own risk.

Do You Even Need Page_Load?

If your page is mainly static or has view state turned off, do you really need Page_Load? If not, get rid of it and reduce visual pollution.

A General Note On Localization

One of the reasons I leave ASPX markup free of event handlers and other logic is awkward localization. If you ever tried to present DataGrid’s header text in multiple languages, you’ll know the pain—it’s next to impossible without building the whole grid in code-behind and filling its headers with resource strings. Other controls follow suit. It’s plain messy to inject localizable text into ASPX markup.

Where Are the Templates?

VS.NET does a fine job scattering page and class templates all over the hard drive. Those cryptic configuration files with GUIDs and other mythical entries aren’t very friendly. I’m hoping in VS.NET 2005 it would easier to add my own templates (like the one above) to the lineup.

Conclusion

I merely presented my opinion on a minimalist template skeleton in this post. I’m surely not criticizing anybody’s approach. I always prefer code-behind to markup because I’m a control freak: I want a debugger, IntelliSense, compile-time checking, etc. “But in 2.0…” I know, I know.

Comments

Comment permalink 1 Bill Brown |
I use Page_Load and InitializeComponent exclusively since they're what comes out when I create a new WebForm. I've been creating new WebForms for 3 years now and I've never had VS.NET 2003 de-wire an event *ever*. Not once.

Perhaps not coincidentally, I've never used the Designer to add controls or edit a control's properties *ever*. Not once.
Comment permalink 2 Milan Negovan |
Yep, it's the designer that messes up events. It happened to me several times and I quickly abandoned it. Been wiring things by hand ever since.
Comment permalink 3 C-J Berg |
It has also happened to me many times, and yes, it's the ugly designer. I think, but I don't know for sure, that it happens if the event handlers aren't fully namespace qualified (as when you wire an event handler by hand, and depend on 'using').

Perhaps the designer doesn't take using's into account, and tries to instantiate an EventHandler for some reason: kaboom, an exception is thrown and the method is left empty. Whatever the real reason is, it's annoying.
Comment permalink 4 David Grant |
Removing InitializeComponent() is a good idea - for me at least.
I don't trust the VS.NET designer for anything, so I hand-wire all my events in the code-behind.
Some people I work with will crack open my hand-coded web forms in design view and start drag-dropping stuff everywhere, which of course makes the HTML look 2nd grade and deletes all the event wirings. infuriating.
Comment permalink 5 Sean Chase |
Interesting route to go. I had to go as far as to have the default view for ASPX pages set to show the markup rather than design view. That eliminated a ton of *other* problems for me personally.
Comment permalink 6 Shane Shepherd |
Milan - Thanks for your insight on this! I do hand code the InitializeComponent, but hadn't thought of removing it! Great idea. This is another area where I had difficulty finding information initially. Most of the documentation I've seen tells you to simply drag and drop controls (in design view), and then double click them to access events code-behind (in VS). They never discuss the wire-up procedure and what VS is ACTUALLY doing behind the scenes...and what if you change you mind about a control and delete it.

I've enjoy your blog immensely...keep it up!
Comment permalink 7 Logan |
/// < summary >
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// < /summary >

Enough said. Put your even handlers in OnInit and they won't get removed.

Emails and Notifications

Would you like to be notified when somebody responds to this post?  Would you like to have these comments emailed to you?

TrackBacks

Sorry, TrackBacks are not allowed.

Submit your comment

Please enter only text since all HTML tags except hyperlinks will be stripped. Hyperlinks will become live links. Any comments with flaming or offensive language will be deleted. Be courteous to other posters. Thank you.

Your name (required):
Your email (optional):
Your site's URL (optional):
Enter this number
Type in the number above:
Comment (required):