Search code examples
c#asp.netpostbackviewstatehtml-select

Dynamically Generated Dropdowns Postback


I'm having some trouble with same Dynamically generated dropdowns and their viewstate.

Long story short, a user will upload an excel file, the file will get parsed and the dropdowns will be created for the appropriate data. This is done on when an asp button is pressed, and the controls are added to a table as follows:

public void generateFromSheet(OrderedDictionary columns, DataTable oppcolumns, List<string> requiredDrops)
    {
        int index = 0;
        foreach (DictionaryEntry entry in columns)
        {
            DropDownList ddl = new DropDownList()
            {
                ID = "ddlMapping" + entry.Key.ToString(),
                DataSource = columns,
                DataTextField = "Key",
                DataValueField = "Value",
                SelectedIndex = index,
                Enabled = requiredDrops.Contains(entry.Key) ? false : true
            };

            ddl.DataBind();

            DropDownList ddl2 = new DropDownList()
            {
                ID = "OpportunityMappingDdl" + index,
                DataSource = oppcolumns,
                DataTextField = "AttributeDisplayName",
                DataValueField = "TableColumnName"
            };
            ddl2.DataBind();


            HtmlTableCell td = new HtmlTableCell()
            {
                ID = "tdMapping" + index
            };
            td.Controls.Add(ddl);

            HtmlTableCell td2 = new HtmlTableCell()
            {
                ID = "tdOppMapping" + index
            };
            td2.Controls.Add(ddl2);

            HtmlTableRow tr = new HtmlTableRow()
            {
                ID = "trMapping" + index
            };
            tr.Cells.Add(td);
            tr.Cells.Add(td2);

            tblFileMapping.Rows.Add(tr);
            index++;
        }
    }

However, on each postback after this, the drop-downs are erased. I've looked online for a solution and usually everything points to recreating the controls using the same id's as when they were created so that their state can be restored from ViewState. I've tried that as follows below by storing what I should create in ViewState:

public void generateFromViewState()
    {
        OrderedDictionary columns = (OrderedDictionary) ViewState["XLColumns"];

        int index = 0;
        foreach (DictionaryEntry entry in columns)
        {
            DropDownList ddl = new DropDownList()
            {
                ID = "ddlMapping" + entry.Key.ToString(),
            };

            DropDownList ddl2 = new DropDownList()
            {
                ID = "OpportunityMappingDdl" + index,
            };

            HtmlTableCell td = new HtmlTableCell()
            {
                ID = "tdMapping" + index
            };
            td.Controls.Add(ddl);

            HtmlTableCell td2 = new HtmlTableCell()
            {
                ID = "tdOppMapping" + index
            };
            td2.Controls.Add(ddl2);

            HtmlTableRow tr = new HtmlTableRow()
            {
                ID = "trMapping" + index
            };
            tr.Cells.Add(td);
            tr.Cells.Add(td2);

            tblFileMapping.Rows.Add(tr);
            index++;
        }
    }

I call this method in the page_load but the controls do not retain their previous data and selected values.

So a couple of things wrong here:

  • On page_load the controls are recreated but their state is not restored.
  • For some technical reasons, my Project Manager mentioned I should not use the Session State to store anything.
  • Another PM advised me that the controls should be regenerated on page_init. BUT since I'm storing the control data in ViewState, this isn't possible because the viewstate isnt ready and my data is null.

Can anyone advise on how to succesfully restore the viewstate for these dynamically generated controls. I've tried searching everything and tried a bunch of solutions online, but nothing I have tried seems to work.

Thanks!


Solution

  • You are doing it right, but you have to recreate the controls with datasource and rebinding all controls again. Without this beeing done, you are creating controls that not match the previous. You can call your first method to do that.