I got “instructed” by a friend to blog some of my more informative forum/list/newsgroup posts, especially the following one which describes the general mechanisms of events with webcontrols, so here you have it. (Names and emails removed to protected the guilty)
Here is an abbreviated look at the lifecycle:
Init
Load ViewState Data
Load PostBack Data
Load
Fire Events
PreRender
Render
To fire control events at a base level, you implement either
IPostBackDataHandler or IPostBackEventHandler.
When you implement IPostBackEventHandler, you are saying that when the
page has determined that your control was the cause of the post back it
will call your RaisePostBackEventHandler implementation during the "Fire
Events" phase. Buttons implement this, for when they are clicked. In
that method you should raise your event.
When you implement IPostBackDataHandler, you are saying that your
control has post data that you need to examine in order to determine if
an event needs to be fired. The page will call your LoadPostData
implementation during the "Load PostBack Data" phase. Here you look at
the post data to determine if you need to raise an event, but you don't
raise it now. If you return true from this, the page will call your
RaisePostDataChangedEvent implementation during the "Fire Events" phase.
Now you raise your event. Textboxes implement this interface, to
determine if they should raise their TextChanged event.
Those are the low-level event mechanisms. However, if you are
implementing a composite control, you have another, higher-level choice,
which is to handle the events raised by your child controls in order to
raise your own events. Sometimes this is done via event bubbling, other
times by creating a whole new event. To do this, progmaticly hook up the
eventhandler as you are creating the child controls. This is the way the
datagrid works.
__
Andy Smith
Chief Code Monkey
[Andy Smith's Blog]
Funny you should blog over this, since I have been grappeling with it the last few days. As a interesting side note, simply implementing System.Web.UI.IPostBackDataHandler doesn't always seem to result in postback's being routed to public bool LoadPostData().
Because of the way that I was generating my asp.net controls (reflection at dynamically proxied objects, which change depending on the database structure, and the current user) and because I was a idiot a couple of times, I was running into weird bugs where I would have three postbacks pending, but after the first postback was called, neither of the other two were delivered. There were also business rules that say things like: "You must add the password to the object before adding a username." Because of all of these problems, I decided that I needed to handle Postback's manually rather then let ASP.net do the lifting for me.
Even though I use three layers of objects to determine rendering order (PropertyGrid, Panel, Row), using three layers made dispatching Postback's a bit more difficult. I ended up overriding the Render() method on each object and used ListArrays to determine what needed to be rendered at each point. The trick was that even though I was rendering three layers of a tree, I put all of my controls in the top level ControlCollection. This made it much easier to dispatch and control postback's carefully. Then I used LoadPostData to write data to my proxied objects via reflection and to the Textboxes and whatnot. What I am striving for is a single control that I throw at any arbitrary object, add a few attributes and voila, a nice data entry system.