Skip to main content

Dynamic user control list

How do you add and remove user controls dynamically on an ASP.NET page?

Dynamic User Control List

There are many ways to do this and here I will present one.

The page container

Start with adding a button and a placeholder on the page. The button will create user controls in the placeholder.

<div>
    <h1>Name list</h1>
    <asp:Button runat="server" Text="Add" OnClick="AddButton_Click" />
    <asp:PlaceHolder runat="server" ID="DynamicNameList" />
</div>

The user control

The user control is very simple. The delete button is tied to an event that will call the Delete-method on the current page.

<div class="name">
    <asp:Label runat="server" Text="Firstname" />:
    <asp:TextBox runat="server" ID="Firstname" />
    <asp:Button runat="server" Text="Delete" OnClick="DeleteButtonClick" />
</div>

The IDynamicControlContainer interface

If you want this to work you need to create an interface that has the Delete-method, and implement this interface on the container page. The reason you want the method on an interface and not on the container page, is to create lower coupling from the user control on the container page.

public interface IDynamicControlContainer
{
    /// <summary>
    /// Deletes the specified control from the container
    /// </summary>
    /// <param name="control">The control.</param>
    void Delete(Control control);
}

Keep state between post backs

We will use the ViewState to save and restore state between postbacks. The only thing we need to keep track on our selves is the control IDs that we added to the user control. When we return on postback, we recreate the controls in the placeholder with the previous IDs and trust that ASP.NET will read back the state of these controls for us. When we change the list by adding and removing a control, we also update the list of IDs in ViewState. Here comes my code behind for the container page.

public partial class NameList : Page, IDynamicControlContainer
{
    protected void Page_Load(object sender, EventArgs e)
    {
        foreach (string id in LoadControlIdList())
        {
            Create(id);
        }
    }

protected void AddButton_Click(object sender, EventArgs e)
{
    Create(null);
}

public void Create(string id)
{
    string targetId = id ?? Guid.NewGuid().ToString();
    var control = LoadControl(&quot;~/NameControl.ascx&quot;);
    control.ID = targetId;

    DynamicNameList.Controls.Add(control);
    SaveControlIdList();
}

public void Delete(Control control)
{
    DynamicNameList.Controls.Remove(control);
    SaveControlIdList();
}

public void SaveControlIdList()
{
    List idList = new List&lt;string&gt;();
    foreach (Control control in DynamicNameList.Controls)
    {
        idList.Add(control.ID);
    }

    ViewState[&quot;IdList&quot;] = idList;
}

public string[] LoadControlIdList()
{
    var list = (List&lt;string&gt;) ViewState[&quot;IdList&quot;];

    if (list == null)
    {
        return new string[0];
    }
    return list.ToArray();
}

}

You can download the complete source code sample here.

comments powered by Disqus