私は基本的に2つのドロップダウンリストをバインドするサーバーコントロールを作成しています。1つは国用、もう1つは州用で、国のselectedindexchangedイベントで州のドロップダウンを更新します。ただし、ポストバックされていません。何かアイデアはありますか? UpdatePanelでそれらをラップするためのボーナスポイント(レンダリングの問題があります。参照するページがないためか)
これが私が持っているものです(いくつかの余分なデータアクセスのものは取り除かれています):
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();
}
}
編集:ビューステートはページ上にあり、ページ上の他のコントロールはポストバックを正しく実行しますが、これだけではありません。
ビューステートはオンになっていますか?
編集:おそらく、レンダリング関数のオーバーライドを再検討する必要があります
protected override void RenderContents(HtmlTextWriter output)
{
ddlCountries.RenderControl(output);
ddlStates.RenderControl(output);
}
代わりに、ドロップダウンリストをコントロールに追加し、デフォルトのRenderContentsを使用してコントロールをレンダリングします。
編集:前のコメントで触れたDennisからの回答を参照してください。
Controls.Add ( ddlCountries );
Controls.Add ( ddlStates );
これらのコントロールをコントロール階層に追加していることがわかりません。試してください:
Controls.Add ( ddlCountries );
Controls.Add ( ddlStates );
コントロールがコントロール階層の一部でない限り、イベントは呼び出されません。
国AutoPostBack
のDropDownList
をtrueに設定する必要があります。
protected override void OnLoad(EventArgs e)
{
// base stuff
ddlCountries.AutoPostBack = true;
// other stuff
}
編集
あなたがこれをしたことを逃した。その場合は、ViewStateが有効になっていることを確認する必要があります。
私は同じ問題を抱えていましたが、AutoPostBackをtrueに設定し、更新パネルでトリガーをドロップダウンリストのコントロールIDに設定し、イベント名をSelectedIndexChangedに設定しました。
<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>
まず、はっきりさせておきたいことがあります。これはポストバック(サーバーへのトリップ)が発生しないのですか、それともポストバックは発生しますが、ddlCountry_SelectedIndexChangedイベントハンドラーに入ることはありませんか?
どちらのケースかはわかりませんが、2番目のケースの場合は、いくつかの提案をいたします。それが最初のケースである場合、以下が参考になります。
2番目のケース(要求が出されてもイベントハンドラーが起動しない)の場合は、次の提案を試してください。
Control.DataBind()を呼び出すと、ビューステートとポストバック情報がコントロールから利用できなくなることに注意してください。ビューステートがオンの場合、ポストバックの間、DropDownListの値はそのまま保持されます(リストは再バインドされません)。 OnLoadで別のDataBindを発行すると、ビューステートデータがクリアされ、SelectedIndexChangedイベントは発生しません。
ビューステートがオフの場合は、毎回リストを再バインドするしかありません。ポストバックが発生すると、Request.Paramsから適切なコントロールに値を入力するための内部ASP.NET呼び出しがあり、OnInitとOnLoadの間に発生したと思われます。この場合、OnInitでリスト値を復元すると、システムがイベントを正しく起動できるようになります。
これを読んでいただきありがとうございます。私が間違っている場合は、是正してください。