Handling Persistance in Asp.Net with Dynamic Controls

I worked on a project a couple of years ago using dynamic controls in an Asp.Net WebForms environment. Managing dynamic controls can be a real hassle.

So when I read Dave Reed’s great article about Viewstate, I wondered if I could do it better now. I worked up a simple example using no Viewstate where values persist across postbacks. Going to the page new resets everything.

The one piece I don’t like is that it uses session for a control count. But it’s a single Int32 per user that get’s stored in session, so it could be worse. Anyway, here’s the code…

Note: the aspx page has a placeholder (phOne) and two buttons (btnAdd) and (btnRemove). EnableViewstate is false on phOne.

using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Web
{
    public partial class Dynamic : System.Web.UI.Page
    {
        private const string KeyNumControls = "DynamicPage_NumControls";
        private const int DefaultControlCount = 2;

        protected override void OnInit(EventArgs e)
        {
            CreateControls(NumberOfControls);
            base.OnInit(e);
        }

        protected override void OnLoad(EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                CreateControls(DefaultControlCount);
            }
        }

        private void CreateControls(int controlCount)
        {
            NumberOfControls = controlCount;
            while(phOne.Controls.Count > NumberOfControls)
            {
                RemoveLastControl();
            }
            while(phOne.Controls.Count < NumberOfControls)
            {
                CreateControl();
            }
        }

        private void RemoveLastControl()
        {
            phOne.Controls.RemoveAt(phOne.Controls.Count - 1);
        }

        private void CreateControl()
        {
            phOne.Controls.Add(new TextBox { EnableViewState = false });
        }

        protected int NumberOfControls
        {
            get
            {
                Session[KeyNumControls] = Session[KeyNumControls] ?? 
                                        DefaultControlCount;
                return (int)Session[KeyNumControls];
            }
            set { Session[KeyNumControls] = value; }
        }

        protected void BtnAddClick(object sender, EventArgs e)
        {
            NumberOfControls += 1;
            CreateControl();
        }

        protected void BtnRemoveClick(object sender, EventArgs e)
        {
            NumberOfControls -= 1;
            RemoveLastControl();
        }
    }
}