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 只在 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 回答
2

DropDownList > SelectedValue 属性> ArgumentOutOfRangeException

所选值不在可用值列表中,并且已加载视图状态或其他状态(已执行回发)。有关详细信息,请参阅备注部分。

资料来源:MSDN

DropDownList > SelectedValue 属性 >备注

(...) 当所选值不在可用值列表中并执行回发时,将引发 ArgumentOutOfRangeException 异常。(...)

资料来源:MSDN

另外,我做了以下测试:

  1. !IsPostBack,添加了一个包含 4 个项目的列表作为数据源,ID 为 1~4
  2. SelectedValue = 5
  3. 添加了一个新项目,使用combo.Items.Add(new ListItem()...)ID 5

我希望将 ID 5 视为组合中的当前选定项目,但它没有发生。

毕竟,看起来这种行为是设计使然。我没有找到更多的信息,所以以下只是我的想法:感觉就像在任意设置控件的数据源之后,开发人员可以自由选择一个不存在的项目,这将没有任何效果。然而,在回发处理上绑定视图状态后,控件的列表被验证(或类似的东西),因此必须相应地对其进行操作。

于 2012-08-06T01:30:30.317 回答