SharePoint Internals – Hristo Pavlov’s Blog

23 May, 2008

Why Should I Specify an ID for Dynamically Created HtmlControls in my WebParts

Filed under: ASP.NET, SharePoint — Tags: , , , , , — hristopavlov @ 2:24 am

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);

 

2 Comments »

  1. […] 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

  2. 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


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: