绑定到DataTable的DataGridViewComboBoxColumn上的DataError

时间:2012-05-03 11:17:44

标签: c# data-binding datagridview datatable datasource

我发现了一些类似问题的主题,但内容似乎略有不同,因此我无法解决问题。

在我的应用程序中,我有一个包含4列的DataTable:

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

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

// 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列的类型都设置为枚举。

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

提前致谢!

3 个答案:

答案 0 :(得分:1)

如何在DataGridView中监听ColumnAdded事件,然后更改类型,而不是添加和删除最后一列:

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;
   } 
}

答案 1 :(得分:0)

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

CNC中 我给DataTable和DataGridViewComboBoxColumn提供了不同的名称,以确保不会导致问题。我现在已将它们更改回来,因此它们具有相同的名称并且仍然有效。

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

答案 2 :(得分:0)

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