Question

I dynamically populate a dropdownlist of all 50 states from an ArrayList on PageLoad. When the user selects the SUBMIT button (btnSubmit_Click event), the SelectedIndex property of the dropdownlist control is always 0 despite what selection the user selects.


Added more code to help troubleshooting. Getting a -1 both from the session variable (bbb) and from the ddlState.selectedindex (bbb).

HTML code in form:

<asp:DropDownList ID="ddlState" runat="server" AutoPostBack="True" 
    onselectedindexchanged="ddlState_SelectedIndexChanged" >
</asp:DropDownList>

Code Behind:

protected void Page_Load(object sender, EventArgs e)
{
    //------------------------------------------------
    // Populates state dropdownlists
    //------------------------------------------------
    if (!IsPostBack)
    {
        GetAllStatesForDdl(ddlDLState);
        GetAllStatesForDdl(ddlOldState);
        GetStatesForDdl(ddlState);
    }
}

private void GetAllStatesForDdl(DropDownList ddlStateList)
{
    AppInputFormProcessor getStates = new AppInputFormProcessor();
    ArrayList States = new ArrayList();
    States = getStates.GetAllStates();
    ddlStateList.DataSource = States;
    ddlStateList.DataBind();
}

private void GetStatesForDdl(DropDownList ddlStateList)
{
    AppInputFormProcessor getStates = new AppInputFormProcessor();
    ArrayList States = new ArrayList();
    States = getStates.GetStates();
    ddlStateList.DataSource = States;
    ddlStateList.DataBind();
}

protected void btnSubmit_Click(object sender, EventArgs e)
{
    int aaa = ddlState.SelectedIndex;
    int bbb = Convert.ToInt32(Session["ddlState"]);
}

protected void ddlState_SelectedIndexChanged(object sender, EventArgs e)
{
    Session["ddlState"] = ddlState.SelectedIndex;
}
Was it helpful?

Solution

When I had trouble with ViewState (that is what l suspect in your case) l used this to restore data to a dynamically populated dropdown object

    public void Page_Load(object sender, EventArgs e){
            if (!IsPostBack)
            {
                Databind();
            }
            else {
                LoadAllViewStates();
            }
    }
    private void Databind()
        {
            DataTable questionnaireDT = null;
            DataTable questionsDT = null;
            DataTable indicatorDT = null;

            DataView tempView = QuestionnaireDS.Select(DataSourceSelectArguments.Empty) as DataView;
            questionnaireDT = tempView.Table;
            ViewState["QuestionnaireDL"] = questionnaireDT;
            QuestionnaireDL.DataSource = ViewState["QuestionnaireDL"];
            QuestionnaireDL.DataBind();

            tempView = QuestionDS.Select(DataSourceSelectArguments.Empty) as DataView;
            questionsDT = tempView.Table;
            ViewState["QuestionList"] = questionsDT;
            QuestionList.DataSource = ViewState["QuestionList"];
            QuestionList.DataBind();

            tempView = IndicatorDS.Select(DataSourceSelectArguments.Empty) as DataView;
            indicatorDT = tempView.Table;
            ViewState["IndicatorLst"] = indicatorDT;
            IndicatorLst.DataSource = ViewState["IndicatorLst"];
            IndicatorLst.DataBind();
        }

        private void LoadAllViewStates()
        {
            QuestionnaireDL.DataSource = ViewState["QuestionnaireDL"];
            QuestionnaireDL.DataBind();

            QuestionList.DataSource = ViewState["QuestionList"];
            QuestionList.DataBind();

            IndicatorLst.DataSource = ViewState["IndicatorLst"];
            IndicatorLst.DataBind();
        }

To restore the selected index, I passed the selectedIndex into a hidden field.

Hope this helps?

By the way, why pass in the DropDownList object as a parameter? Instead call a parameterless function and populate the DropDownList object within the function.

Also, ensure that ViewState isnt switched off.

OTHER TIPS

In your example, you are trying to get the selected value from a session variable, but there's no code shown that actually sets anything in the session.

Even if you have some sort of async call that sets a session variable, this is a very dangerous practice: as soon as someone opens up a 2nd tab, you risk the chance of data corruption.

This should work for you. However, I am sort of confused why you are passing the dropdown to the function to get the states. Do you have multiple dropdowns to be filled? I think we need to see your html to be of more help.

protected void Page_Load(object sender, EventArgs e)
{
    if(!IsPostBack)
        GetStatesForDdl(ddl);
}

 private void GetStatesForDdl(DropDownList ddlStateList)
 {
     AppInputFormProcessor getStates = new AppInputFormProcessor();
     ArrayList States = new ArrayList();
     States = getStates.GetStates();
     ddlStateList.DataSource = States;
     ddlStateList.DataBind();
 }

First you will need to populate and databing the list only in a if( !IsPostBack ) { ... statement.

Next - Session["ddlState"] is never being populated, not sure where you want to populate this but you could do it in the selected index changed as you stated. this should work if you are not calling DataBind() on the postback.

How about this:

protected void GetStatesForDdl(DropDownList ddlStateList)
{
    //remove event handler
    ddlStateList.SelectedIndexChanged -= new EventHandler(ddlState_SelectedIndexChanged);

    //business as usual
    AppInputFormProcessor getStates = new AppInputFormProcessor();
    ArrayList States = new ArrayList();
    States = getStates.GetStates();
    ddlStateList.DataSource = States;
    ddlStateList.DataBind();

    // then force it to select desired index
    ddlStateList.SelectedIndex = (int)Session["ddlState"];

   //ok, stick it back to control
   ddlStateList.SelectedIndexChanged += new EventHandler(ddlState_SelectedIndexChanged);
}

I suggest usage of local variables in ViewState instead of Session and SelectedValue instead of SelectedIndex.

This could help you out:

While binding the drop down list specify the DataTextField and the DataValueField properties. The reason for getting the selected index as 0 during the Submit is because the drop down does not contain unique values associated to each item in it. And remember that the property specified in DataValueField should be unique. i.e. each item in the drop down should be uniquely identifiyable.

For example, consider that the States class is specified like this:

public class State
{
    public string Name { get; set; }
    public string Id { get; set; }
}

Now the drop down list should be binded as given below. Here for every States Item the 'Id' property is unique.

ddlStateList.DataSource = States;
ddlStateList.DataTextField = "Name";
ddlStateList.DataValueField = "Id";
ddlStateList.DataBind();

If you have ViewState disabled, then you have to save the SelectedIndex into the Session and on the Page_Load, you always reload the data and set the index directly. When you bind the datasource, send the index as a parameter to default the index (from session) and set the SelectedIndex to this number after you call DataBind().

When you say, you don't use ViewState, does it mean, you have it disabled for the page or your dropdown list? That could be your problem. I know a lot of people have asked you this, but I don't see any answer from you to suggest whether or not you are using viewstate. When your user makes a selection and your page posts back, you still need viewstate, so your page knows what the user selects even after posting back. Then its upto you to either save it in session or viewstate.

On the other hand, if your viewstate is enabled, add one piece of code on a new page to see when the problem starts to appear. Remember to not touch the viewstate and to go with the default. To start with, add a page with a dropdown and a button and bind it to 2 dummy values and read the user selection on post back. As you keep adding more code and controls, if the problem re-appears, you'll be able to find out what line of code is giving you grief.

Hope this helps.

If you bind your drop down list items in OnInit all of the view state will be handled automatically by the framework. If you bind it in Page_Load you're not adding them until after the viewstate is already applied. Move it to OnInit and you'll not have to worry about it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top