为什么将ComboBox.SelectedValue设置为null会导致ArgumentNullException?

时间:2013-05-15 07:34:28

标签: c# winforms combobox datasource nullreferenceexception

为什么将SelectedValue的{​​{1}}设置为ComboBox导致null

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

null不能SelectedValue。实际上,在我尝试将其设置为null时,其值 null

在我的实际代码中,这不会在构造函数中发生,我并没有明确地将其设置为null。代码使用的变量恰好是null。在尝试设置null之前,我可以通过检查变量不是null来修复它。但我不明白的是为什么我无法将其设置为SelectedValue值。

代码编辑:DataSource现在包含ValueMembers值实际为null

的项目
null

5 个答案:

答案 0 :(得分:5)

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不为空,则设置者会调用Find()并将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为空,则会抛出异常。

我猜测当将ComboBox插入容器(例如Form)时,dataManager仅设置为非null,这就是为什么当它不在容器中时它不会爆炸。< / p>

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

但是,这似乎不太正确,因为您报告了NullReferenceException,这显然会引发ArgumentNullException

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

答案 1 :(得分:2)

我的猜测是,这可能会错过ArgumentNullException而不是NullReferenceException(在属性设置器的实现中引发)。

在快速检查您提供的代码时(加上Main var form1 = new Form1()方法),我发现我实际上并没有像您描述的那样NullReferenceException,而是{ {1}}就像我期望的那样。

您确定是否正确记录了异常类型?

<强>更新

正如Matthew Watson所描述的那样,ArgumentNullException指示的参数实际上是ArgumentNullException

答案 2 :(得分:0)

也许是因为如果SelectedValue的属性ValueMember为Nothing,那么SelectedValue将在SelectedItem上返回.ToString()。

答案 3 :(得分:0)

在button_click上,此代码被删除并删除 ArgumentNullException

if (comboBoxPays.SelectedValue == null)
{
  id_pays = 0;
}
else
  id_pays = int.Parse(comboBoxPays.SelectedValue.ToString());

答案 4 :(得分:0)

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