8

为什么设置SelectedValueaComboBoxnull导致 a ArgumentNullException

仅当 ComboBox 实际上是表单的一部分时才会发生异常。我可以设置SelectedValue为各种没有意义的值或类型,但我不能将其设置为null.

不是SelectedValue不能null。实际上,它的值 null在我尝试将其设置为null.

在我的真实代码中,这不会发生在构造函数中,我也没有明确地将其设置为null. 该代码使用的变量恰好是null. 我可以通过null在尝试设置SelectedValue. 但我不明白为什么我不能将它设置为一个null值。

代码编辑:DataSource 现在包含 ValueMembers 值实际所在的项目null

using System.Collections.Generic;
using System.Windows.Forms;

public class Form1 : Form {
    public Form1() {
        var comboBox1 = new ComboBox();
        Controls.Add(comboBox1);
        comboBox1.ValueMember = "Key";
        comboBox1.DisplayMember = "Value";
        comboBox1.DataSource = new List<Record> {
            new Record {Key = "1", Value = "One"}, 
            new Record {Key = null, Value = "null"}
        };
        comboBox1.SelectedItem = null;          // no problem
        comboBox1.SelectedValue = "";           // no problem
        comboBox1.SelectedValue = new object(); // no problem
        comboBox1.SelectedValue = null;         // ArgumentNullException!!
    }
}

public class Record {
    public string Key { get; set; }
    public string Value { get; set; }
}
4

5 回答 5

6

检查其中属性的实现Reflector如下所示:

public object SelectedValue
{
    get
    {
        if ((this.SelectedIndex != -1) && (this.dataManager != null))
        {
            object item = this.dataManager[this.SelectedIndex];
            return this.FilterItemOnProperty(item, this.valueMember.BindingField);
        }
        return null;
    }
    set
    {
        if (this.dataManager != null)
        {
            string bindingField = this.valueMember.BindingField;
            if (string.IsNullOrEmpty(bindingField))
            {
                throw new InvalidOperationException(SR.GetString("ListControlEmptyValueMemberInSettingSelectedValue"));
            }
            PropertyDescriptor property = this.dataManager.GetItemProperties().Find(bindingField, true);
            int num = this.dataManager.Find(property, value, true);
            this.SelectedIndex = num;
        }
    }
}

所以这似乎取决于this.dataManager不为空。

如果this.dataManager不为 null,则 setter 将调用setFind()key您设置的值SelectedValue

internal int Find(PropertyDescriptor property, object key, bool keepIndex)
{
    if (key == null)
    {
        throw new ArgumentNullException("key");
    }
    if (((property != null) && (this.list is IBindingList)) && ((IBindingList) this.list).SupportsSearching)
    {
        return ((IBindingList) this.list).Find(property, key);
    }
    if (property != null)
    {
        for (int i = 0; i < this.list.Count; i++)
        {
            object obj2 = property.GetValue(this.list[i]);
            if (key.Equals(obj2))
            {
                return i;
            }
        }
    }
    return -1;
}

key如果为null,它将引发异常。

我猜dataManager只有当 ComboBox 插入容器(例如表单)时才设置为非 null,这就是为什么它不在容器中时不会爆炸的原因。

(实际上,dataManager当您将Control.DataSource属性设置为非空时,将设置为非空。)

但是,这似乎不太正确,因为您报告了 aNullReferenceException并且这显然会抛出ArgumentNullException.

[编辑] 这确实是一个ArgumentNullExeption; OP 已相应更新。

于 2013-05-15T07:43:44.467 回答
2

My guess was that this may be a miss on what should be an ArgumentNullException rather than a NullReferenceException (thrown in the property setter's implementation).

On quickly checking the code you provided (plus a Main method with var form1 = new Form1()), though, I find that I do not actually get a NullReferenceException like you describe but rather an ArgumentNullException like I expect I should.

Are you sure that you noted the exception type correctly?

UPDATE:

As Matthew Watson describes, the parameter indicated by the ArgumentNullException is, in fact, key.

于 2013-05-15T07:44:46.700 回答
0

可能是因为如果 SelectedValue 的 ValueMember 属性为 Nothing,则 SelectedValue 将在 SelectedItem 上返回 .ToString()。

于 2013-05-15T07:42:06.103 回答
0

我知道这是一个老问题,但我现在有同样的错误,我发现我无法设置 SelectedValue = null 但我确实设法将它设置为 DBNull.Value

于 2015-01-15T12:37:19.597 回答
0

在 button_click 上,此代码执行并删除了ArgumentNullException

if (comboBoxPays.SelectedValue == null)
{
  id_pays = 0;
}
else
  id_pays = int.Parse(comboBoxPays.SelectedValue.ToString());
于 2013-07-20T11:18:52.583 回答