DataGridView 再次抓住了我,我无法弄清楚为什么我使用以下代码出现单元格格式错误。我在网上找到的所有解决方案都不起作用/不适合。在加载时我设置:
Dim dtAlign As New DataTable ' creating and filling a DataTable
dtAlign.Columns.Add("ID", GetType(Int32))
dtAlign.Columns.Add("Text", GetType(String))
dtAlign.Rows.Add(1, "Left")
dtAlign.Rows.Add(2, "Right")
dtAlign.Rows.Add(3, "Center")
Dim cola As DataGridViewComboBoxColumn = CType(Me.dgList.Columns("ColAlign"), DataGridViewComboBoxColumn)
cola.DisplayMember = "Text"
cola.ValueMember = "ID"
cola.DataSource = dtAlign ' assign datatable as a combobox col. datasource
这些列是通过 VS GUI 设置的(此列:名称 = 'ColAlign',宽度 = 100,DataPropertyName = 'ColAlign',列类型 = DataGridViewComboBoxCell 等)。它在将数据填充到 DGV 之前的断点处工作,我看到提供了一个有效的数据表:
当我没有将任何数据加载到列中时,我可以看到正确的 ComboBox 选择:
但是,如果我在此列的数据源中添加数据,则会出现单元格格式错误(说该值无效)并且该值显示为显示成员文本:
数据库列不可为空(此时始终为 1),并且为 INT。我什至尝试对它进行投射,以确保它没有混淆,即作为字符串:
CAST(ColAlign as INT) as ColAlign
尽管如此,我还是得到了错误,我不知道什么是错误的,但显然数据表中的 1 与数据库结果集中的 1 不同。过去我遇到过 Int16 与 INT 不匹配的问题,但 Int32 总是在数据库中与 INT 不匹配。乃至:
CAST(1 as INT) as ColAlign
...不起作用。顺便说一句,我只是这样分配数据:
Me.dgList.DataSource = ds.Tables(0)
通常,它必须是非常简单的东西,我所缺少的。我什至会感谢提示如何进一步调试此类问题。
编辑:
我还尝试创建一个按钮并在 onClick 中编写了一个代码:
Me.dgList.Rows(1).Cells("ColAlign").Value = 1
这很好用。
编辑2:
我在 DataSet 和 DataSource 之间插入了一个带有固定数据类型列的 DataTable(如果是 ComboBoxColumns,则为 int32),这应该排除提供了错误的数据类型并且它仍然不起作用......
Dim dtGrid As New DataTable
dtGrid.Columns.Add("ID", GetType(Int32))
dtGrid.Columns.Add("FormID", GetType(Int32))
dtGrid.Columns.Add("ColName", GetType(String
dtGrid.Columns.Add("IsVisible", GetType(Boolean))
dtGrid.Columns.Add("ColWidth", GetType(String))
dtGrid.Columns.Add("ColAlign", GetType(Int32))
dtGrid = ds.Tables(0)
Me.dgList.AutoGenerateColumns = False
Me.dgList.DataSource = dtGrid
编辑 3
另一个调试:
Dim dtTemp As DataTable
Dim dgwcb As DataGridViewComboBoxColumn = CType(Me.dgList.Columns("ColAlign"), DataGridViewComboBoxColumn)
dtTemp = CType(dgwcb.DataSource, DataTable)
MsgBox("ValueMember name = " & dgwcb.ValueMember.ToString & vbCrLf &
"DisplayMember name = " & dgwcb.DisplayMember.ToString & vbCrLf &
"DataPropertyName = " & dgwcb.DataPropertyName.ToString & vbCrLf &
"Value = " & Me.dgList.Rows(2).Cells("ColAlign").Value.ToString & vbCrLf &
"ToString = " & dgwcb.ToString)
DataSet Visualizer 中的 dtTemp 看起来不错,并且在 MsgBox 中检查的所有内容都是预期的(ValueMember = "ID",DisplayMember = "Text",DataPropertyName = "ColAlign",Value = 2 /我将其设置为 2 以进行更改/)。
解决方法:
唯一可行的方法是将带有 ComboBoxCell 的列留空,并在设置 DGV 数据源后手动填充它们,将它们缩小到 Int32(请注意,它们已经在 SQL 和 dtGrid 中缩小了):
For ir = 0 To dtGrid.Rows.Count - 1
Me.dgList.Rows(ir).Cells("ColAlign").Value = CInt(dtGrid.Rows(ir)("ColAlign"))
Next
由于我很少将 DGV 与 ComboBoxCell 一起使用,因此我可以接受这个“解决方案”。
编辑 4 / 变通方法 2
我创建了第二个相同的(结构)dtGrid2,并将值逐行和逐个单元格复制到第二个中,瞧——它适用于 dtGrid2而不适用于原始 dtGrid!因此,当我从数据库中提取数据时,原始正确的列数据类型会被重新输入错误的内容。我怀疑这仅发生在 SQLiteDataAdapter 上,因为我过去没有使用 SqlDataAdapter 体验过它。一个简化的代码来解释:
Dim dtGrid As New DataTable
Dim dtGrid3 As New DataTable
dtGrid.Columns.Add("ID", GetType(Int32))
dtGrid.Columns.Add("ColName", GetType(String))
dtGrid.Columns.Add("ColAlign", GetType(Int32))
' load data from DB. ...and corrupt the dtGrid...
dtGrid = ds.Tables(0).DefaultView.ToTable
dtGrid3.Columns.Add("ID", GetType(Int32)) ' identical columns
dtGrid3.Columns.Add("ColName", GetType(String)) ' identical columns
dtGrid3.Columns.Add("ColAlign", GetType(Int32)) ' identical columns
For ir = 0 To dtGrid.Rows.Count - 1 ' copy all values to new identical table
dtGrid3.Rows.Add({dtGrid(ir)("ID"), dtGrid(ir)("ColName"), dtGrid(ir)("ColAlign")})
Next
Me.dgList.DataSource = dtGrid3 ' works!!! Doesn't with dtGrid...