I'm creating a server control that basically binds two dropdown lists, one for country and one for state, and updates the state dropdown on the country's selectedindexchanged event. However, it's not posting back. Any ideas why? Bonus points for wrapping them in an UpdatePanel (having rendering issues; maybe because I don't have a Page to reference?)
Here's what I have (with some extra data access stuff stripped out):
public class StateProv : WebControl
{
public string SelectedCountry;
public string SelectedState;
private DropDownList ddlCountries = new DropDownList();
private DropDownList ddlStates = new DropDownList();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
IList<Country> countries = GetCountryList();
IList<State> states = new List<State>();
if (SelectedCountry != null && SelectedCountry != "")
{
states = GetStateList(GetCountryByShortName(SelectedCountry).CountryShortName);
}
else
{
states.Add(new State { CountryId = 0, Id = 0, StateLabelName = "No states available", StateLongName = "No states available", StateShortName = "" });
}
ddlCountries.DataSource = countries;
ddlCountries.DataTextField = "CountryLongName";
ddlCountries.DataValueField = "CountryShortName";
ddlCountries.SelectedIndexChanged += new EventHandler(ddlCountry_SelectedIndexChanged);
ddlCountries.AutoPostBack = true;
ddlStates.DataSource = states;
ddlStates.DataTextField = "StateLongName";
ddlStates.DataTextField = "StateShortName";
ddlCountries.DataBind();
ddlStates.DataBind();
if (!string.IsNullOrEmpty(SelectedCountry))
{
ddlCountries.SelectedValue = SelectedCountry;
if (!string.IsNullOrEmpty(SelectedState))
{
ddlStates.SelectedValue = SelectedState;
}
}
}
protected override void RenderContents(HtmlTextWriter output)
{
ddlCountries.RenderControl(output);
ddlStates.RenderControl(output);
}
private IList<Country> GetCountryList()
{
//return stuff
}
private IList<State> GetStateList(Country country)
{
//return stuff
}
private IList<State> GetStateList(string countryAbbrev)
{
Country country = GetCountryByShortName(countryAbbrev);
return GetStateList(country);
}
private Country GetCountryByShortName(string countryAbbrev)
{
IList<Country> list = dataAccess.RetrieveQuery<Country>();
//return stuff
}
private IList<State> GetAllStates()
{
//return stuff
}
protected void ddlCountry_SelectedIndexChanged(object sender, EventArgs e)
{
IList<State> states = GetStateList(GetCountryList()[((DropDownList)sender).SelectedIndex]);
ddlStates.DataSource = states;
ddlStates.DataBind();
}
}
Edit: Viewstate is on the page, and other controls on the page perform postbacks correctly, just not this.
This question is related to
c#
asp.net
drop-down-menu
custom-server-controls
selectedindexchanged
I had the same problem but got round it by setting AutoPostBack to true and in an update panel set the trigger to the dropdownlist control id and event name to SelectedIndexChanged e.g.
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always" enableViewState="true">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddl1" EventName="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<asp:DropDownList ID="ddl1" runat="server" ClientIDMode="Static" OnSelectedIndexChanged="ddl1_SelectedIndexChanged" AutoPostBack="true" ViewStateMode="Enabled">
<asp:ListItem Text="--Please select a item--" Value="0" />
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
You need to set AutoPostBack
to true for the Country DropDownList
.
protected override void OnLoad(EventArgs e)
{
// base stuff
ddlCountries.AutoPostBack = true;
// other stuff
}
Edit
I missed that you had done this. In that case you need to check that ViewState is enabled.
I can't see that you're adding these controls to the control hierarchy. Try:
Controls.Add ( ddlCountries );
Controls.Add ( ddlStates );
Events won't be invoked unless the control is part of the control hierarchy.
First, I would like to clarify something. Is this a post back (trip back to server) never occur, or is it the post back occurs, but it never gets into the ddlCountry_SelectedIndexChanged event handler?
I am not sure which case you are having, but if it is the second case, I can offer some suggestion. If it is the first case, then the following is FYI.
For the second case (event handler never fires even though request made), you may want to try the following suggestions:
Beware that when calling Control.DataBind(), view state and post back information would no longer be available from the control. In the case of view state is on, between post back, values of the DropDownList would be kept intact (the list does not to be rebound). If you issue another DataBind in OnLoad, it would clear out its view state data, and the SelectedIndexChanged event would never be fired.
In the case of view state is turned off, you have no choice but to rebind the list every time. When a post back occurs, there are internal ASP.NET calls to populate the value from Request.Params to the appropriate controls, and I suspect happen at the time between OnInit and OnLoad. In this case, restoring the list values in OnInit will enable the system to fire events correctly.
Thanks for your time reading this, and welcome everyone to correct if I am wrong.
Source: Stackoverflow.com