C# – ListBox not getting selected items

asp.netcdrop-down-menulistbox

I have a ListBox which I am adding ListItems to in a codebehind. The problem I'm having is the ListBox is not seeing the selected items. I have the ListBox being populated dynamically depending on what the user selects from a DropDownList, so the DropDownList has AutoPostBack set to true. I think this is somehow causing the problem.

My SelectedIndexChanged method, which is used whenever an item in the DropDownList is selected, calls a method called PopulateListBox. Here's what those methods looks like:

protected void SelectedIndexChanged(object sender, EventArgs e)
{
    string typeStr = type.SelectedItem.Text;
    MyType = Api.GetType(typeStr);
    PopulateListBox();
}

private void PopulateListBox()
{
    listbox.Items.Clear();
    foreach (PropertyInfo info in MyType.GetProperties())
        listbox.Items.Add(new ListItem(info.Name));
}

For what it's worth, here are the DropDownList and ListBox:

<asp:DropDownList runat="server" ID="type" width="281px" OnSelectedIndexChanged="SelectedIndexChanged" AutoPostBack="true" />

<asp:ListBox runat="server" ID="listbox" width="281px" height="200px" selectionmode="Multiple" />

What I am trying to do is add a List of strings (strings being the selected items) as a session variable upon clicking a submit button. The button redirects to a new page after the List has been added to the session. Going through in debugger, the List of strings is empty at the point where I add it to the session.

listbox.GetSelectedIndices() returns nothing.

Update

I can access the selected items if I do not make a change in the DropDownList. The ListBox is initially populated on page load, and if I make selections they are recognized. If I select something from the DropDownList and the ListBox is repopulated, the selections are not recognized.

My Page_Load method does only two things. It initializes my Api variable and calls PopulateDropDown, which looks like this:

private void PopulateDropDown()
{
    foreach (Type t in Api.GetAllTypes())
        type.Items.Add(new ListItem(t.Name));
    string typeStr = type.Items[0].Text;
    Type = Api.GetType(typeStr);
    PopulateListBox();
}

Best Answer

The problem is that you call PopulateDropDown() on every single Page_Load(), which calls PopulateListBox(), which clears the listbox and repopulates it. By clearing the listbox, you clear the selection.

You need to replace your call to PopulateDropDown() in the Page_Load() with the following code. The issue that I think you don't realize is that the page is loaded on every postback -- and that in the page life cycle, the page load occurs before the event. So by selecting a drop down item, you execute the Page_Load() event first (which indirectly executes the LoadListBox method, clearing the selection). The following code will populate the drop down list the first time the page loads only. Keep it the same wherever else you are using the load dropdown method:

protected void Page_Load(object sender, EventArgs e)
{
    // Do your API code here unless you want it to occur only the first
    // time the page loads, in which case put it in the IF statement below.
    if (!IsPostBack)
    {
        PopulateDropDown();
    }
}

The IsPostBack returns a boolean indicating whether the server side code is running because the page is loading for the first time ("false") or as a post back ("true").

As I said elsewhere, keep in mind that a listbox with potential for multiple selected values must be handled differently than one with potential for a single selection. Don't reference listbox.SelectedItem, but rather:

foreach (ListItem item in lbFullNames)
{
    if (item.Selected)
    {
        // TODO: Whatever you are doing with a selected item.
    }
}
Related Topic