2012-05-03 32 views
1

我发现了几个类似的问题,但内容看起来有些不同,因此我无法解决我的问题。DataGridViewComboBoxColumn上的DataError绑定到DataTable

在我的应用程序数据表有包含4列:

  • UINT16
  • UINT64
  • UINT64
  • 一种自定义枚举由2个值的类型。

为了显示此DataTable的值,我创建了一个DataGridView并将此表设置为数据源。到现在为止还挺好。我希望枚举字段列包含组合框,并且运行到DataGridViewComboBoxColumn类型中。我有一些问题得到它的工作,但eventualy结束了使用以下方法:

// Create the 4 datarows 

// Add the datarows to the data table 

// Set the data table as the data source for the data grid view 

// Remove the column that represents the enumeration 

// Add a DataGridViewComboBoxColumn to the DataGridView as replacement 

我创建了DataGridViewComboBoxColumn如下:

DataGridViewComboBoxColumn cb = new DataGridViewComboBoxColumn(); 
cb.HeaderText = "My header text"; 
cb.ValueType = typeof(MyEnumType); 
cb.DataSource = Enum.GetValues(typeof(MyEnumType)); 
cb.FlatStyle = FlatStyle.System; 
cb.Name   = "Name"; //Same name as the DataColumn and the now deleted DataGridViewColumn 
cb.DataPropertyName = "Name"; //Same name as the DataColumn and the now deleted DataGridViewColumn 
cb.DisplayStyle  = DataGridViewComboBoxDisplayStyle.Nothing; 

dataGridView.Columns.Add(cb); 

一旦我的应用程序启动时我将数据从文本阅读该文件被放置在一个结构中,上面提到了4种数据类型的字段。然后我将这些字段添加到DataTable中,如下所示:

DataRow row = dataTable.NewRow(); 
row["Name of the UInt16 column"] = mystruct.theUInt16; 
row["Name of the UInt64 column"] = mystruct.theUInt64; 
row["Name of the UInt64 column"] = mystruct.theUInt64_2; 
row["Name of the enum column"]  = mystruct.theEnumValue;    
dataTable.Rows.Add(row); 

启动时,DataError事件被重复调用。然而,单元格的内容却得到了正确的填充。 (我在多次点击错误后看到这个)禁用DataError事件(例如分配一个空处理程序)是我不想做的事情。

我觉得有某种类型的不匹配。 (也许是枚举类型和显示字符串?)但这只是一个猜测。 dataTable列和datagridview列都具有设置为枚举的类型。

我希望有人能指出我正确的方向。

在此先感谢!

回答

0

我设法找到一个适合我的需求的解决方法。这个方法仍然和我原来的文章一样。我让DataTable中的枚举名为“colMyEnumTypeTable”,数据类型是字符串而不是MyEnumType。然后我删除了这一列,并添加了名为“colMyEnumType”的DataGridViewComboBoxColumn,其中包含DataPropertyName“colMyEnumTypeTable”,并且也是string类型。然后,我将枚举值转换为字符串时,将它们添加到数据表中,当提取我使用Enum.Parse来再次检索枚举值。不再有DataError调用。

-edit- 我给了DataTable和DataGridViewComboBoxColumn不同的名称以确保不会导致问题。现在我已经改变了他们,所以他们有相同的名字,它仍然有效。

-edit2- 而不是为comboboxcolumn设置DataSource属性,我通过将它们添加到Items属性来添加枚举值。 (在转换为字符串后)

1

而是添加和删除最后一列,怎么样监听事件在DataGridView然后改变类型则:

dataGridView.ColumnAdded += DataGridViewColumnAdded; 
dataGridView.DataSource = dataTable; 

private void DataGridViewColumnAdded(Object sender, DataGridViewColumnEventArgs e) 
{ 
    if(e.Column.ValueType == typeof(MyEnumType)) 
    { 
     DataGridViewComboBoxCell cb = new DataGridViewComboBoxCell(); 
     cb.ValueType  = typeof(MyEnumType); 
     cb.DataSource  = Enum.GetValues(typeof(MyEnumType)); 
     cb.FlatStyle  = FlatStyle.System; 
     cb.DisplayStyle  = DataGridViewComboBoxDisplayStyle.Nothing; 
     e.Column.CellTemplate = cb; 
    } 
} 
+0

我无法获得您提出的解决方案。最后一条语句给出错误:不能隐式地将类型'System.Windows.Forms.DataGridViewComboBoxColumn'转换为'System.Windows.Forms.DataGridViewCell'(CS0029) – Arnold4107176

+0

不确定是否相关,但如果我将“cb”更改为“ cb.CellTemplate“在最后一行,它编译,但我得到一个运行时异常。 (System.InvalidCastException)与消息:“为CellTemplate提供的值必须是类型System.Windows.Forms.DataGridViewTextBoxCell或从它派生。 ” – Arnold4107176

+0

@ Arnold4107176 - 对不起,我刚刚复制你的东西,它应该真的是一个' DataGridViewComboBoxCell'。让我更新它 – SwDevMan81

0

将枚举直接分配给带有数据表的组合框的原因是“值无效”错误是DataGridViewComboBoxColumn中的枚举和DataRow中的整数值之间的类型差异(不管列类型是否设置为枚举类型,枚举总是作为其基础类型存储在DataRow中)。 例如如果您在致电row["Name of the enum column"] = mystruct.theEnumValue;
后回读row["Name of the enum column"] ,那么它不会是您刚分配的枚举,而是其基础值。 此文章:DataGridView linked to DataTable with Combobox column based on enum有一个使用键值数据源的替代解决方案。

相关问题