Search code examples
asp.netpage-init

couple of problems for those controls dynamically created in the page_init


Based on certain condition, I have created a few checkboxes, dropdownlists and textboxes dynamically in the Page_Init().In the same page, I have a Submit button that is created during the design time (in the aspx page). Following is the part of the code. The textbox’s visibility is controlled by the checkbox.

Now I have two problems need to solve: (1) ddl.selectedIndex is always initialized to 0 not -1. But in the event handler Sumbit_Click(), the ddl.selectedIndex is 0 even I didn’t select any item. (2) Also even the checkbox is checked, during the postback, the textbox doesn’t show. Is there any way to fix it?

DropDownList ddl = new DropDownList();
ddl.ID = "ddl" + id;
ddl.DataSource = subCallReasonEntityList;
ddl.DataTextField = "myText";
ddl.DataValueField = "id";                          
ddl.DataBind();
ddl.SelectedIndex = -1;
cell.Controls.Add(ddl);

CheckBox cb = new CheckBox();
cb.ID = "cb" + id;
cb.ClientIDMode = ClientIDMode.Static;
cell.Controls.Add(cb);
cell.Controls.Add(new LiteralControl("<br />"));

TextBox tb = new TextBox();
tb.ID = "txt" + id;
tb.ClientIDMode = ClientIDMode.Static;
tb.Attributes.Add("style", "display:none");
cb.Attributes.Add("onclick", "return cbOtherClicked('" + cb.ClientID + "', '" + tb.ClientID + "')");
cell.Controls.Add(tb);

function cbOtherClicked(control1, control2) {
var cbOther = document.getElementById(control1);
var txtOther = document.getElementById(control2);

if (cbOther.checked) {
    txtOther.style.display = "block";
}
else {
    txtOther.style.display = "none";
}
}

Solution

  • The issue here is that your dynamic controls aren't maintaining ViewState.

    KEY: Modify the control after you add it to the form/page etc . If you modify the properties before it is added to the form , Values added will not make it to viewState and will be lost on postback. Atleast do this as a standard.

    So, do it like this:

    DropDownList ddl = new DropDownList();
    // add first this control 
    cell.Controls.Add(ddl);
    // now set the values
    ddl.ID = "ddl" + id;
    ddl.DataSource = subCallReasonEntityList;
    ddl.DataTextField = "myText";
    ddl.DataValueField = "id";                          
    ddl.DataBind();
    ddl.SelectedIndex = -1;
    

    And make sure you always recreate all the dynamic controls on every postback.

    When we add any control dynamically it play “catch-up” with the page life cycle once they are added. Once the control is added to the “Controls" collection, all the events that it missed are fired.

    This leads to a very important conclusion: you can add dynamic controls at any time during the page life cycle until the “PreRender" event. Even when you add the dynamic control in the “PreRender" event, once the control is added to the “Controls" collection, the “Init", “LoadViewState", “LoadPostbackdata", “Load", and “SaveViewstate" are fired for this control.