2

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

在我的应用程序中,我有包含 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 列都将类型设置为枚举。

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

提前致谢!

4

3 回答 3

1

与其添加和删除最后一列,不如在然后更改类型时监听ColumnAdded事件: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;
   } 
}
于 2012-05-03T13:07:50.623 回答
0

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

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

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

于 2012-05-04T07:46:17.783 回答
0

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

于 2016-04-06T11:52:32.153 回答