views:

691

answers:

3

I have form with 2 DDL named

State and City

State:

<asp:UpdatePanel ID="States" runat="server" UpdateMode="Conditional">
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="States"EventName="SelectedIndexChanged" />
        </Triggers>
        <ContentTemplate>
            <asp:DropDownList ID="States" runat="server"
            AutoPostBack="True" DataSourceID="StatesObjectDataSource" 
            AppendDataBoundItems="true" 
                onselectedindexchanged="States_SelectedIndexChanged">
            <asp:ListItem Value="-1" Text="- None -"/>    
            </asp:DropDownList>
            <asp:ObjectDataSource ID="StatesObjectDataSource" runat="server" 
                onselecting="StatesObjectDataSource_Selecting" 
                SelectMethod="GetStates" 
                TypeName="Something">
            </asp:ObjectDataSource>
        </ContentTemplate>
    </asp:UpdatePanel>

City:

<asp:DropDownList ID="Cities" runat="server">
        </asp:DropDownList>

When they choose a state I want to populate the Cities DDL with all the cities for that state.

In code behind I am able to get to

States_SelectedIndexChanged(object sender, EventArgs e)

and i try to populate the Cities DDL by this

Cities.Items.Add(new ListItem(city,city));

However, I do not see my Cities DDL populated

+1  A: 

I recommend creating a private property in the ViewState that holds the collection of physical objects. Then add the object to that list then databind the list of objects to the drop down.

Page Behind

<asp:DropDownList runat="server" ID="ddlCity" DataValueField="Key" DataTextField="Value">
</asp:DropDownList>

Code Behind

private List<KeyValuePair<string, string>> ListData
{
    get { return (List<KeyValuePair<string, string>>) (ViewState["ListData"] ??     
                 (ViewState["ListData"] = new List<KeyValuePair<string, string>>())); }
    set { ViewState["ListData"] = value; }
}

protected void States_SelectedIndexChanged_SelectedIndexChanged(object sender, EventArgs e)
{
  ListData.Add(new KeyValuePair<string, string>(ddlCitys.SelectedValue, ddlCitys.SelectedValue));
  ddlCitys.DataSource = ListData;
  ddlCitys.DataBind();
}

The get statement also employs lazy loading on the ListData property so you will never encounter a null reference exception when accessing the list.

Chris Marisic
+1  A: 

If at all possible, I would suggest using the CascadingDropDown Extender instead of the UpdatePanel. There's no use reinventing that wheel, and the Toolkit control uses web services instead of partial postbacks (much faster).

Dave Ward
Dave: I obtain my data using a SUBSONIC data access layer and do not have webservice. Would the CascadingDropDown extender still work with a List<> object.Also, can you shed some light as to why you recommend this over the Update Panel?
You can bind the CascadingDropDown to any data source when you create its service method. Avoid the UpdatePanel when possible because it causes performances issues when overused. Only use them when you really must (ViewState important, etc).
Dave Ward
+1  A: 

Place your city DropDownList inside the update panel.

Chris Pebble