What Is Happening:
Following the best practices for implementing WebParts we often create our controls dynamically in the CreateChildControls() method. However if your web part uses a ToolPart your server event handlers (such as OnClick handlers) may not be called.
When It Is Happening:
This problem happens with your dynamically created System.Web.UI.HtmlControls if you don’t specify the ID of the controls.
HtmlButton button = new HtmlButton();
tableCell.Controls.Add(button);
button.InnerText = “Create”;
button.ServerClick += new EventHandler(ButtonCreate_click);
The problem is only occurring if your web part implements a ToolPart.
Why It Is Happening:
What is happening is that, in the case there is a ToolPart involved, the CreateChildControls() comes before OnLoad(). So when we recreate our controls without giving them names they won’t have any name assigned until a later stage. At this later stage they will be given system generated names such as “ctl01“. However this later stage happens after the post back events (such as OnClick) are raised. When ASP.NET tries to call the event handlers it is not able to locate your controls because they don’t have an ID yet and no match can be found to the control that has generated the post back and is specified in the __EVENTTARGET hidden field:
private void RaisePostBackEvent(NameValueCollection postData)
{
if (this._registeredControlThatRequireRaiseEvent != null)
{
this.RaisePostBackEvent(this._registeredControlThatRequireRaiseEvent, null);
}
else
{
stringstr = postData["__EVENTTARGET"];
bool flag = !string.IsNullOrEmpty(str);
if (flag || (this.AutoPostBackControl != null))
{
Control control = null;
if (flag)
{
control = this.FindControl(str);
}
if ((control != null) && (control.PostBackEventHandler != null))
{
stringeventArgument = postData["__EVENTARGUMENT"];
this.RaisePostBackEvent(control.PostBackEventHandler, eventArgument);
}
}
else
{
this.Validate();
}
}
}
The problem with the different order of events was reported as well for example in the following post: http://www.schaeflein.net/blog/2004/03/29/OrderOfEventsInWebPart.aspx. I did a further experiment and found that this is exactly the reason for the problem. For example when I called manually base.Load() at the beginning of the CreateChildControls() everything was working fine even without explicitly giving a name to my controls.
How To Solve It:
Remember to always give names (ID) to your dynamically generated controls. This not only resolves this particular issue but also guarantees that system generated names will not cause same controls to have different IDs between different responses from the same page, which you don’t really want.
HtmlButton button = new HtmlButton();
tableCell.Controls.Add(button);
button.InnerText = “Create”;
button.ID = “btnCreate”;
button.ServerClick += new EventHandler(ButtonCreate_click);
[...] Why Should I Specify an ID for Dynamically Created HtmlControls in my WebParts [...]
Pingback by Links (5/25/2008) « Steve Pietrek - Everything SharePoint — 25 May, 2008 @ 11:38 pm
Somehow i missed the point. Probably lost in translation
Anyway … nice blog to visit.
cheers, Mediterranean!
Comment by Mediterranean — 21 June, 2008 @ 7:32 pm