【发布时间】:2017-08-14 20:45:37
【问题描述】:
我有一个用枚举值填充的 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
[空值参数]从数据源返回DBNull时,将属性设置为指定值。
这些是我唯一能看到对 DBNull 的引用的地方。
有没有办法修复这个异常,或者阻止 RadioGroup 在获得焦点时尝试更新数据源?
【问题讨论】:
-
RadioGroup是什么? -
看看RadioButtonList。该帖子包含一个示例,展示了如何将它与枚举一起使用。
-
@RezaAghaei 正如您提供的链接所述,
RadioButtonList是 WebForms 控件,而不是 WinForms 控件。对于我正在开发的控件库,这不是一个合适的解决方案。 -
查看我的答案,我提供了一个 Windows 窗体控件;)它实际上是一个单选
ListBox,它在项目附近显示单选按钮。因此它具有可靠的内置数据绑定支持。 -
@RezaAghaei 这不是一个坏主意,但我正在开发一个也建立在另一个第三方控件库上的控件库,所以我想要一个专门针对 RadioGroup 的解决方案。不过,也许其他时间值得研究一下,谢谢。
标签: c# winforms .net-3.5 radio-group