使用ComboBox将DataGridView绑定到DataTable不起作用

编程入门 行业动态 更新时间:2024-10-26 09:29:31
本文介绍了使用ComboBox将DataGridView绑定到DataTable不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试创建绑定到DataTable的DataGridView,其中一列是ComboBox.该代码运行,但绑定后(而不是绑定数据时)出现以下错误:System.ArgumentException:DataGridViewComboBoxCell值无效.

在DataGridView中,其中一列是DataGridViewComboBoxColumn,它使用枚举(命名为structureType)作为源:

//ColumnStructure//this.ColumnStructure.ValueType = typeof(structureType);this.ColumnStructure.DataSource =枚举GetValues(typeof(structureType));this.ColumnStructure.HeaderText =结构";this.ColumnStructure.Name ="ColumnStructure";this.ColumnStructure.DataPropertyName =结构";//

当我不使用DataTable填充DataGridView时,它就可以正常工作:

structureType?结构= GetStructure(部分);dgvObjectTypes.Rows.Add(名称,类型,结构,计数);

现在,我想改用DataTable,但无法使其正常工作.DataTable的创建如下:

DataTable表= new DataTable();table.Columns.Add("Name",typeof(string));table.Columns.Add("Type",typeof(string));table.Columns.Add("Structure",typeof(DataGridViewComboBoxCell));table.Columns.Add("Count",typeof(int));

其他列效果很好,但我无法使"Structure"列正常工作.这是我尝试创建组合框的方法:

var cb = new DataGridViewComboBoxCell();cb.ValueType = typeof(structureType);cb.DataSource = Enum.GetValues(typeof(structureType));cb.Value =(structureType)结构;

之后,我只为表创建行,并将表设置为DataGridView的数据源:

table.Rows.Add(name,type,cb,count);dgv.DataSource = table;

我读过很多帖子,其中指出在组合框中使用枚举会引起问题(例如:

I'm trying to create a DataGridView bound to a DataTable where one column is a ComboBox. The code runs but I get the following error after binding (not when data is bound): System.ArgumentException: DataGridViewComboBoxCell value is not valid.

In the DataGridView one of the columns is a DataGridViewComboBoxColumn that uses an enum (named structureType) as it's source:

// ColumnStructure // this.ColumnStructure.ValueType = typeof(structureType); this.ColumnStructure.DataSource = Enum.GetValues(typeof(structureType)); this.ColumnStructure.HeaderText = "Structure"; this.ColumnStructure.Name = "ColumnStructure"; this.ColumnStructure.DataPropertyName = "Structure"; //

When I populate the DataGridView without using a DataTable, it works just fine:

structureType? structure = GetStructure(part); dgvObjectTypes.Rows.Add(name, type, structure, count);

Now I would want to use a DataTable instead, but can't get it to work. The DataTable is created as follows:

DataTable table = new DataTable(); table.Columns.Add("Name", typeof(string)); table.Columns.Add("Type", typeof(string)); table.Columns.Add("Structure", typeof(DataGridViewComboBoxCell)); table.Columns.Add("Count", typeof(int));

Other columns work great but I can't get the "Structure" column to work. Here's how I've tried to create the combobox:

var cb = new DataGridViewComboBoxCell(); cb.ValueType = typeof(structureType); cb.DataSource = Enum.GetValues(typeof(structureType)); cb.Value = (structureType)structure;

After that I just create the rows for the table and and set the table as datasource for the DataGridView:

table.Rows.Add(name, type, cb, count); dgv.DataSource = table;

I've read a lot of posts where it has been stated that using enums in comboboxes causes problems (this for example: DataGridView linked to DataTable with Combobox column based on enum), but that doesn't seem to be the case here. I even tried to use explicitly typed arrays of strings but still get the same error. I think I'm doing something wrong with the DataGridViewComboBoxCell.

What could be the problem?

解决方案

It seems like the step you are missing is providing the Names and Values for the CBO. The DataTable can store the value, and the DGV can display the related name, but you need to help provide the translation.

private enum structureType { None, Circle, Square, Pyramid} ... dtStruct = new DataTable(); dtStruct.Columns.Add("Name", typeof(string)); dtStruct.Columns.Add("Type", typeof(string)); dtStruct.Columns.Add("Structure", typeof(structureType)); dtStruct.Columns.Add("Count", typeof(int)); // autogen columns == true dgv2.DataSource = dtStruct; // create DataSource as list of Name-Value pairs from enum var cboSrc = Enum.GetNames(typeof(structureType)). Select( x => new {Name = x, Value = (int)Enum.Parse(typeof(structureType),x) } ).ToList(); // replace auto Text col with CBO col DataGridViewComboBoxColumn cb = new DataGridViewComboBoxColumn(); cb.ValueType = typeof(structureType); cb.DataSource = cboSrc; cb.DisplayMember = "Name"; // important cb.ValueMember = "Value"; // important cb.HeaderText = "Structure"; cb.DataPropertyName = "Structure"; // where to store the value dgv2.Columns.Remove(dgv2.Columns[2]); // remove txt col dgv2.Columns.Add(cb); cb.DisplayIndex = 2; // add data dtStruct.Rows.Add("Ziggy", "Foo", structureType.Circle, 6);

The first part creates the DataTable, note that the Structure column type is structureType (or often int). The DataTable will be storing data, not DataGridViewComboBoxCell elements. In cases where the data comes from a database, that column would be int since structureType would not be a known type.

A DataSource is then created from the enum names and values. This provides the means for the control to show the name, yet store the value in the DataTable.

If the DGV is set to auto generate columns, you will need to replace the default TextBoxColumn with a ComboBoxColumn. This is being done after the DataSource has been set, but before any data is added. When the data comes from a DB (and so there is not usually an empty, typed table) you can use the ColumnAdded event to swap out one column for another.

The important thing when adding the CBO column is to set the ValueMember and DsiplayMember properties to provide the Value <-> Name translation and DataPropertyName so it knows where to store the selected value in the DataTable.

更多推荐

使用ComboBox将DataGridView绑定到DataTable不起作用

本文发布于:2023-11-10 06:06:43,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1574556.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:绑定   不起作用   ComboBox   DataGridView   DataTable

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!