6

最近、ASP.NET DropDownList内で奇妙な動作を発見しました。これは、誰かが説明できることを願っています。

基本的に、私が遭遇している問題は、ポストバックの前にデータバインディングを実行し、データSelectedValueアイテムのリスト内に存在しない値にを設定すると、呼び出しがまったく効果がないことです。ただし、ポストバックでは、同じ呼び出しが失敗しますArgumentOutOfRangeException()

'cmbCountry'にはSelectedValueがありますが、これはアイテムのリストに存在しないため無効です。パラメータ名:値

私は次のコードを使用しています。

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        cmbCountry.DataSource = GetCountries();
        cmbCountry.DataBind();

        cmbCountry.SelectedValue = ""; //No effect
    }
    else
    {
        cmbCountry.SelectedValue = ""; //ArgumentOutOfRangeException is thrown
    }
}

protected List<Country> GetCountries()
{
    List<Country> result = new List<Country>();

    result.Add(new Country() { ID = Guid.NewGuid(), Description = "Test" });
    result.Add(new Country() { ID = Guid.NewGuid(), Description = "Test1" });
    result.Add(new Country() { ID = Guid.NewGuid(), Description = "Test2" });
    result.Add(new Country() { ID = Guid.NewGuid(), Description = "Test3" });

    return result;
}

public class Country
{
    public Country() { }
    public Guid ID { get; set; }
    public string Description { get; set; }
}

誰かが私のためにこの動作の原因を明確にし、回避策があるかどうかアドバイスしてもらえますか?

4

2 に答える 2

2

DropDownList > SelectedValueプロパティ> ArgumentOutOfRangeException

選択した値が使用可能な値のリストになく、ビューステートまたは他のステートがロードされています(ポストバックが実行されました)。詳細については、「備考」セクションを参照してください。

ソース:MSDN

DropDownList>SelectedValueプロパティ>備考

(...)選択した値が使用可能な値のリストになく、ポストバックが実行されると、ArgumentOutOfRangeException例外がスローされます。(...)

ソース:MSDN

また、次のテストを行いました。

  1. に、データソースとして4!IsPostBackつのアイテム、ID 1〜4のリストを追加しました
  2. セットするSelectedValue = 5
  3. combo.Items.Add(new ListItem()...)ID5を使用して新しいアイテムを追加しました

コンボで現在選択されているアイテムとしてID5が表示されると思っていましたが、実際には発生しませんでした。

結局のところ、この動作は仕様によるもののようです。これ以上の情報が見つからないので、以下は私の考えです。コントロールのデータソースを任意に設定した後、開発者は存在しないアイテムを自由に選択できるようになります。これは単に効果がありません。ただし、ポストバック処理でビューステートをバインドした後、コントロールのリストが検証される(またはそのようなもの)ため、それに応じて操作する必要があります。

于 2012-08-06T01:30:30.317 に答える
2

なぜこのように設計されたのかはわかりませんが、DropDownListはPostBackでこの例外をスローするだけです...ILSpyのセッターコードは次のとおりです。

public virtual string SelectedValue
{
    get { ... }
    set
    {
        if (this.Items.Count != 0)
        {
            if (value == null || (base.DesignMode && value.Length == 0))
            {
                        this.ClearSelection();
                return;
            }
            ListItem listItem = this.Items.FindByValue(value);


/********** Checks IsPostBack here **********/
            bool flag = this.Page != null &&
                        this.Page.IsPostBack &&
                        this._stateLoaded;
            if (flag && listItem == null)
            {
                throw new ArgumentOutOfRangeException("value",
                    SR.GetString("ListControl_SelectionOutOfRange", new object[]
                        {
                            this.ID,
                            "SelectedValue"
                        }));
            }
            if (listItem != null)
            {
                this.ClearSelection();
                listItem.Selected = true;
            }
        }
        this.cachedSelectedValue = value;
    }
}

これを回避するには、SelectedValueを空の文字列ではなくnullに設定します。

于 2012-08-06T02:18:50.103 に答える