11

基本的に国用と州用の 2 つのドロップダウン リストをバインドし、国の 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();
    }
}

編集: Viewstate はページ上にあり、ページ上の他のコントロールはポストバックを正しく実行しますが、これは正しくありません。

4

5 に答える 5

5

ビューステートはオンになっていますか?

編集: おそらく、レンダリング関数のオーバーライドを再検討する必要があります

  protected override void RenderContents(HtmlTextWriter output)
    {
        ddlCountries.RenderControl(output);
        ddlStates.RenderControl(output);
    }

代わりに、ドロップダウン リストをコントロールに追加し、デフォルトの RenderContents を使用してコントロールをレンダリングします。

編集: 以前のコメントで言及したデニスからの回答を参照してください:

Controls.Add ( ddlCountries );
Controls.Add ( ddlStates );
于 2009-02-20T16:45:04.633 に答える
4

これらのコントロールをコントロール階層に追加しているようには見えません。試す:

Controls.Add ( ddlCountries );
Controls.Add ( ddlStates );

コントロールがコントロール階層の一部でない限り、イベントは呼び出されません。

于 2009-02-20T17:30:57.253 に答える
3

AutoPostBackCountry を trueに設定する必要がありますDropDownList

protected override void OnLoad(EventArgs e)
{
    // base stuff

    ddlCountries.AutoPostBack = true;

    // other stuff
}

編集

私はあなたがこれをしたことを逃しました。その場合、ViewState が有効になっていることを確認する必要があります。

于 2009-02-20T16:45:39.810 に答える
1

私は同じ問題を抱えていましたが、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>
于 2011-11-14T12:48:37.183 に答える
0

まず、何かを明確にしたいと思います。これはポストバック(サーバーへのトリップバック)が発生することはありませんか、それともポストバックが発生しますが、ddlCountry_SelectedIndexChangedイベントハンドラーに入ることがありませんか?

どちらのケースかはわかりませんが、2番目のケースの場合は、いくつかの提案をすることができます。それが最初のケースである場合、以下は参考までにあります。

2番目のケース(要求が行われたとしてもイベントハンドラーが起動しない)の場合、次の提案を試してみてください。

  1. Request.Params [ddlCountries.UniqueID]をクエリして、値があるかどうかを確認します。ある場合は、イベントハンドラーを手動で起動します。
  2. ビューステートがオンである限り、ポストバックでない場合にのみリストデータをバインドします。
  3. ビューステートをオフにする必要がある場合は、リストデータバインドをOnLoadではなくOnInitに配置します。

Control.DataBind()を呼び出すと、ビューステートとポストバック情報がコントロールから利用できなくなることに注意してください。ビューステートがオンの場合、ポストバックの間に、DropDownListの値はそのまま保持されます(リストはリバウンドされません)。OnLoadで別のDataBindを発行すると、そのビューステートデータがクリアされ、SelectedIndexChangedイベントが発生することはありません。

ビューステートがオフになっている場合は、毎回リストを再バインドするしかありません。ポストバックが発生すると、Request.Paramsから適切なコントロールに値を入力するための内部ASP.NET呼び出しがあり、OnInitとOnLoadの間の時間に発生すると思われます。この場合、OnInitでリスト値を復元すると、システムはイベントを正しく発生させることができます。

これをお読みいただきありがとうございます。私が間違っている場合は、皆さんが訂正することを歓迎します。

于 2009-02-20T17:14:04.080 に答える