2017-03-22 25 views
2

我有一个使用枚举值填充的WinForms RadioGroup。我的问题是,当控制获得焦点,它会尝试更新与System.DBNull所选择的项目,这是不是一个枚举的有效值,我最终得到了异常:如何防止RadioGroup尝试设置SelectedItem焦点?

类型的“对象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

[空值参数]将该属性设置为当一个的DBNull从数据源返回的指定的值。

这些是我能看到的DBNull参考的地方。

有没有办法来解决这个异常,或者防止RadioGroup在获取焦点时尝试更新数据源?

+0

什么是RadioGroup? –

+0

看一下[RadioButtonList](http://stackoverflow.com/a/41355419/3110834)。该文章包含一个示例,展示如何将它与枚举一起使用。 –

+0

@RezaAghaei如您所提供的链接所说,“RadioButtonList”是一个WebForms控件,而不是WinForms控件。这不是我正在开发的控制库的合适解决方案。 – Rachel

回答

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,这不是有效的枚举。