ASP.NET - don't load data on Page_Load

I've recently had to fix a lot of bad code other people wrote, so I thought I'd give my 2 cents on ASP.NET data loading / binding.

This discussion refers to developing User Controls or Custom Controls. As the developer of such controls, you have to make sure the code that's using your User Control can decide whether or not to perfrom resource-intensive data loading and binding.

For that reason, the worst possible place to put code that, for example, loads data from the database is on the Page_Load event. This event is raised by the framework and cannot be programmatically controlled from other controls.

public partial class UserControls_WebUserControl : System.Web.UI.UserControl
{
    //this event handler is automatically added when you create a new user control in Visual Studio
    //do not perform resource-intensive processing here, such as database calls 
    protected void Page_Load(object sender, EventArgs e)
    {
        //this is usually the wrong place to put this code
        if (!Page.IsPostBack)
        {
            //get a list of customers from the database and bind it to a GridView
        }
    }
}

Instead, a good place to put such code is on the DataBind() method, like this:

public partial class UserControls_WebUserControl : System.Web.UI.UserControl
{
    public override void DataBind()
    {
        //this is a better place to put resource-intensive code
        //get a list of customers from the database and bind it to a GridView
    }
}

The Page or Control that contains your User Control can now decide when it is necessary to load the data. For example, if I call DataBind() on the page itself, according to the documentation, this also calls the DataBind() method on the controls it contains, and all the other descendants in the control hierarchy.

However, as the developer of the hosting page, I can also have the option NOT to call DataBind on my Page, but instead to call DataBind explicitly on each child User Control as needed.

In this case I can use my own checks to decide whether it is necessary for a specific User Control to load its data, based, for example, on whether I've hidden the control, or whether it's a postback, or an AsyncPostBack from an UpdatePanel, and so on.

The MSDN documentation for this method is as follows:

Public method     DataBind          Binds a data source to the invoked server control 
                                    and all its child controls. (Inherited from Control.)
Protected method  DataBind(Boolean) Binds a data source to the invoked server control and 
                                    all its child controls with an option to raise the 
                                    DataBinding event. (Inherited from Control.)

The DataBind method was the right place to put database code in my project, however this is by no means the only correct way to do it. You can design your own architecture, for example by creating appropriate methods in your own BaseUserControl class and then inheriting all your UserControls from it. The point that I'm trying to make is that you should design your controls in such a way that other controls and control developers can decide if and when data loading should happen (otherwise they will have to spend a lot of time to redesign/rewrite code in your control).