2017-03-22 54 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,這不是有效的枚舉。