2

これは明らかな解決策がある一般的なシナリオのように見えますが、どういうわけか私はそれに遭遇していません。

イベントにDropDownListバインドされたイベントハンドラーSelectedIndexChangedAutoPostback="true"、があります。これは意図したとおりに機能します。

イベントハンドラーは値が変更されたときに実行されますが、クライアント側でjQueryを使用してスクリプトを介して値が変更された場合、ユーザーが値を変更したとき(およびドロップダウンのonchangeイベントが発生したとき)にポストバックがトリガーされます。次に、サーバー側のコードは、サーバーが最後に状態を確認してから値が変更されていないことを検出します。したがって、イベントハンドラーはサーバー側で実行されません。

ビューステートを介してロードされるもののように見えますが、無効にしViewStateても効果はありません。

  1. ページは、値「A」が選択された状態でドロップダウンをレンダリングします。
  2. ユーザーがドロップダウンリストを値「B」に変更します。
  3. 値は自動的にサーバーに送信され、SelectedIndexChangedイベントハンドラーが実行されます。
  4. クライアントスクリプトを実行して、を使用してクライアントの値を「A」に戻しますjQuery.val()
  5. ユーザーは値を「B」に戻します。
  6. 値は自動的にサーバーに送信されますが、サーバーが最後にページをレンダリングしたときに値が「B」であったため、SelectedIndexChangedイベントハンドラーは実行されません。

クライアント側

<asp:DropDownList ID="dlst" runat="server" AutoPostBack="true" OnSelectedIndexChanged="dlst_SelectedIndexChanged">
    <asp:ListItem Text="A" Value="A" />
    <asp:ListItem Text="B" Value="B" />
</asp:DropDownList>

<asp:Button ID="btnChange" runat="server" Text="Change" OnClientClick="return changeDDL(this,event)" />
<script type="text/javascript">
    function changeDDL(sender, e) {
        var dlst = $("#<%= dlst.ClientID %>");
        dlst.val(dlst.val() === "A" ? "B" : "A");
        return false;
    }
</script>

サーバ側

protected void dlst_SelectedIndexChanged(object sender, EventArgs e)
{
    btnChange.Text = dlst.SelectedValue == "A" ? "Change B" : "Change A";
}
4

1 に答える 1

2

.Net Frameworkリファレンスソースをデバッグした後、問題は実装の奥深くにありDropDownList、動作を変更するためにクラスを再実装または継承せずに修正することはできないと結論付けました。

DropDownListクラスには、interfaceメソッドの実装がLoadPostData()あります。IPostBackDataHandler

内部では、ドロップダウンで現在選択されている値のインデックスが、ドロップダウンで設定されているときにロードされるか、デフォルトで設定されているプロパティLoadPostData()と比較されます。SelectedIndexViewState0EnableViewState="false"

このOnSelectedIndexChanged()メソッドは、によって呼び出されRaisePostDataChangedEvent()ます。この名前が示すように、ビューステート/デフォルトデータと比較して投稿データが変更された場合にのみ呼び出されます。したがって、現在選択されているインデックスがビューステート/デフォルトのインデックスと一致する場合、SelectedIndexChangedイベントは発生しません。

私の場合、2つのことが問題を引き起こす可能性があります。

  1. 有効にすると、現在のインデックス値はからロードされViewStateた値と一致するため、起動しません。SelectedIndexViewStateSelectedIndexChanged
  2. ViewState無効にすると、値SelectedIndexはデフォルトでに設定される0ため、現在のインデックス値が0である場合、は起動SelectedIndexChangedしません。

DropDownList.LoadPostData()

protected virtual bool LoadPostData(String postDataKey, NameValueCollection postCollection) { 
    //{snip...}
    int n = Items.FindByValueInternal(selectedItems[0], false);

    if (SelectedIndex != n) {
        SetPostDataSelection(n); // Calls ListControl.SetPostDataSelection() and sets Items[selectedIndex].Selected = true;
        return true;
    } 

    return false; 
}

後で、Page投稿データが変更されたコントロールをクラスが通過するときにOnSelectedIndexChanged、変更が検出された場合はドロップダウンのメソッドが呼び出されます。この場合、ドロップダウンの投稿データは変更されていないため、イベントは発生しません。

DropDownList.RaisePostDataChangedEvent()

protected virtual void RaisePostDataChangedEvent() { 
    //{snip...}
    OnSelectedIndexChanged(EventArgs.Empty); 
} 
于 2012-10-27T20:29:07.717 に答える