如何阻止RadioGroup尝试在Focus上设置SelectedItem?

时间:2017-03-22 15:51:48

标签: c# winforms .net-3.5 radio-group

我有一个填充了枚举值的WinForms RadioGroup。我的问题是当控件获得焦点时,它会尝试使用System.DBNull更新所选项,这不是枚举的有效值,我最终得到异常:

  

类型的对象' System.DBNull'无法转换为' MyNamespace.MyEnumType'

我有一个自定义的RadioGroup类,其中包含以下用于添加项目和获取/设置所选值的代码:

/// <summary>
/// sets the items, using reflection to get the display member and value
/// </summary>
public void SetItems<T>(IEnumerable<T> values, string valueMember, string displayMember)
{
    Type t = typeof(T);

    PropertyInfo displayProperty = t.GetProperty(displayMember);
    PropertyInfo valueProperty = t.GetProperty(valueMember);

    if (displayProperty == null)
        throw new ArgumentException(string.Format("Property {0} is not found on class {1}", displayMember, t.FullName), "displayMember");

    if (valueMember == null)
        throw new ArgumentException(string.Format("Property {0} is not found on class {1}", valueMember, t.FullName), "valueMember");

    Properties.Items.Clear();

    foreach (var val in values)
    {
        object desc = displayProperty.GetValue(val, null);
        Properties.Items.Add(new RadioGroupItem(valueProperty.GetValue(val, null), desc == null ? string.Empty : desc.ToString()));
    }
}

/// <summary>
/// accessor for the selected value
/// </summary>
public object SelectedValue
{
    get { return GetSelectedValue(); }
    set { SetSelectedValue(value); }
}


private object GetSelectedValue()
{
    if (SelectedIndex < 0 || SelectedIndex >= Properties.Items.Count)
    {
        if (DataBindings.Count > 0 && DataBindings["SelectedValue"] != null)
            return DataBindings["SelectedValue"].DataSourceNullValue;
        else
            return null;
    }

    return Properties.Items[SelectedIndex].Value;
}

private void SetSelectedValue(object selectedItem)
{
    SelectedIndex = FindSelectedValue(selectedItem);
}

private int FindSelectedValue(object value)
{
    for (int i = 0; i < Properties.Items.Count; i++)
    {
        object val = Properties.Items[i].Value;

        if ((val != null && val.Equals(value)) || (val == null && value == null))
        {
            return i;
        }
    }

    return -1;
}

以下是从文件后面的代码初始化的方法:

myRadioGroup.SetItems<KeyValuePair<MyEnum, string>>(
    new List<KeyValuePair<MyEnum, string>>() 
    {
        new KeyValuePair<MyEnum, string>(MyEnum.VALUE_A, "Value A"), 
        new KeyValuePair<MyEnum, string>(MyEnum.VALUE_B, "Value B")
    },
"Key", "Value");

// adds the binding
myRadioGroup.DataBindings.Add(new Binding("MyPropertyName", myDataSource, "SelectedValue", true, DataSourceUpdateMode.OnValidation, MyEnum.NONE));

当我打电话

时,我不清楚为什么我会收到此异常
myRadioGroup.Focus();

GotFocus事件被命中,SetSelectedValue方法被调用并返回正常的null值。我唯一能想到的是GetSelectedValue显示DataSourceNullValue作为System.DBNull,尽管在构造函数中将其设置为MyEnum.NONE,但即使我在调试模式下更正它仍然给了我同样的例外。

同样根据MSDN page about this binding constructor

  

[null value parameter]在从数据源返回DBNull时将属性设置为指定的值。

这是我可以看到对DBNull的引用的唯一地方。

有没有办法修复此异常,或阻止RadioGroup在获得焦点时尝试更新数据源?

1 个答案:

答案 0 :(得分:0)

我想我找到了一个解决方案... Binding构造函数设置.NullValue,而我需要设置.DataSourceNullValue

// adds the binding
Binding b = new Binding("MyPropertyName", myDataSource, "SelectedValue", true, DataSourceUpdateMode.OnValidation, MyEnum.NONE);
b.DataSourceNullValue = MyEnum.NONE;
myRadioGroup.DataBindings.Add(b);

根据this MSDN blog post

  

DataSourceNullValue指定数据源的哪个值被视为空值,指定应将哪个值写回数据源以获取空值

默认值为System.DBNull,因此它似乎尝试将空值写为System.DBNull,这对于枚举无效。