Dynamically add user control under UpdatePanel in ASP.NET

There are many ways to do this in ASP.NET. I have to say this is a complicated topic for me.

I am not going to tell you all sorts of ways to accomplish this since some guys out there have already done this. And I learned from them. Here is how I like to do it.

I would like to give some important background first.

Page life cycle (simplify) : Init->Load viewstate->Load->Save viewstate->Event Handler

Viewstate : properties and values of your controls, event handler included!

Postback : the page life cycle will be gone through in each postback, so, if you have add some controls dynamically, you have to do the same in the follow up postbacks.

Events : The event handler works with the control’s id, the id is generated according to how you add them, so the ordering of adding controls is crucial.

That is all you need to know. So it would be wise to add you controls at Init stage if it is possible. If you add your controls at Load stage, you will need to add event handlers for them manually. This will be a large load of work that I will avoid. I will now go through how to add control.

It is very likely that you click something or have some events, then you want some controls to appear. The event handler may be your first choice putting in your dynamic add controls code. But this lead to a problem, event handler comes later then Page_Load, don’t even mention Page_Init is even before that. So, I use a work around which is about _doPostBack. Most of the postback involved a Javascript function _doPostBack(). It will pass two parameters to you Page object, which are __EVENTTARGET and __EVENTARGUMENT. __EVENTTARGET is the control that trigger the postback and __EVENTARGUMENT is the value it contains. This is what I do.

public partial class myPage : System.Web.UI.Page
{
   public myPage()
   {
      //add a event handler to the Page Init event
      Init += new EventHandler(Page_MyInit);
   }
   protected void Page_MyInit(object sender, EventArgs e)
   {
       //get the values of the control Id and it's value
       string target = Request.Params.Get("__EVENTTARGET");
       string argument = Request.Params.Get(__EVENTARGUMENT); 
       //add dynamic controls if the event is what you want
       if( ...check target and argument...)
       {
            //I like to use place holder to handle dynamic controls, just add a static place holder
            Control uc1 = Page.LoadControl( ...path of your control... );
            placeHolder1.Controls.Add(uc1);
       }
   }
}

This should let you add your controls just fine. If your postback is not using _doPostBack, you can try another approach by Request.Form and loop through it. dev|sushi posts have cover that. And now we need to add those controls in each postback to keep them on the page, I use the dumbest approach which is remembering the controls I have added in the session and check them in Page_Init. Add the following just after the above if {}

if (Session["whatever"] != null && !isFirstTime)
{
    ... add user control just like before ...
}

There is one thing you need to beware, this make me head ache for a day. remenber don’t do this.

if( ...check target and argument...) { add control a }
if( ...check target and argument...) { add control b }
if( ...check target and argument...) { add control c }
if (Session["whatever"] != null && !isFirstTime) { add control a}
if (Session["whatever"] != null && !isFirstTime) { add control b}
if (Session["whatever"] != null && !isFirstTime) { add control c}

This will mess up your controls ordering, do this instead

if( ...check target and argument...) { add control a }
if (Session["whatever"] != null && !isFirstTime) { add control a}
if( ...check target and argument...) { add control b }
if (Session["whatever"] != null && !isFirstTime) { add control b}
if( ...check target and argument...) { add control c }
if (Session["whatever"] != null && !isFirstTime) { add control c}

As for the viewstate, I recommend you clear it whenever you don’t need it. I simply call Viewstate.Clear() when user click on the menu. Or disable viewstate on dynamic controls by Control.EnableViewState = false when you are using UpdatePanel. Because UpdatePanel will do it for you with javascript. But beware when you design your user controls, give each control and their sub controls a unique id. I think UpdatePanel is restoring values by component’s id which is a common way of ajax. I had a id conflict and it gives me Sys.WebForms.PageRequestManagerServerErrorException.

I hope this helps. ^^

Advertisements

9 thoughts on “Dynamically add user control under UpdatePanel in ASP.NET

  1. Hello Maxi326,
    Thanks for your post excellent post.
    I am always getting empty string whenever i am trying to retrieve __EVENTTARGET AND __EVENTARGUMENT. How can i solve this problem. Can you please check my code below and let me know where am i going wrong?

    .aspx:

    .cs:

    public myPage()
    {
    //add a event handler to the Page Init event
    Init += new EventHandler(Page_MyInit);
    }
    protected void Page_MyInit(object sender, EventArgs e)
    {

    //get the values of the control Id and it’s value
    string target = Request.Params[“__EVENTTARGET”];
    string argument = Request.Params.Get(“__EVENTARGUMENT”);
    }

    Thanks a million!

    • Hi Amodi,

      This is actually an interesting question indeed.
      The __DoPostback javascript is for javascript postback only. In other words, control which naturally will postback like submit button will not generate such javascript postback, it just postback. So, if you want to catch __EVENTTARGET and __EVENTARGUMENT, you will have a control like maybe a drop down list and set the autopostback attribute to ‘true’. Then if it fires the event, I think you will be able to catch those two variables. If you want to catch a button event, I think you have to find some work around.

      I Hope this could help you.

      Maxi

    • Actually my friend, I might just have that work around too.
      set the UseSubmitBehavior attribute of your button to false so that it is no longer a form submit button. You will be able to catch it too.

  2. Hello Maxi,
    I have a button “btnUseAjax”, this button is used as a trigger to updatePanel and in updatePanel i have a placeHolder to which i want to add a user control dynamically whenever “btnUseAjax” is clicked. Its working perfect. But the problem is the “UserControls” event are not firing? :((

    The code is as follows:

    public myPage()
    {
    //add a event handler to the Page Init event
    Init += new EventHandler(Page_MyInit);
    }
    protected void Page_MyInit(object sender, EventArgs e)
    {

    //get the values of the control Id and it’s value
    string target = this.Request[“__EVENTTARGET”];
    string argument = Request.Params.Get(“__EVENTARGUMENT”);
    if (!string.IsNullOrEmpty(target))
    {
    if (target.Equals(“btnAjax”))
    {
    Control uc1 = Page.LoadControl(“abcl.ascx”);
    placeHolder1.Controls.Add(uc1);
    }
    }
    }

    Please help,

    Thanks.

Leave a Reply

Please log in using one of these methods to post your comment:

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