简体   繁体   English

DataGridView单元格格式错误

[英]DataGridView Cell Formatting Error

DataGridView caught me again, I cannot figure out, why I get cell formatting error with following code. DataGridView再次抓住了我,我无法弄清楚,为什么在以下代码中出现单元格格式化错误。 None of the solutions I found on the net wouldn't work/fit either. 我在网上找到的所有解决方案均无法使用。 On load I set: 加载时我设置:

    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

The columns are set via VS GUI (this column: Name = 'ColAlign', Width = 100, DataPropertyName = 'ColAlign', column type = DataGridViewComboBoxCell, etc.). 通过VS GUI设置列(此列:名称='ColAlign',宽度= 100,DataPropertyName ='ColAlign',列类型= DataGridViewComboBoxCell等)。 It, works, at a breakpoint just before filling data into DGV, I see a valid datatable is provided: 它可以在将数据填充到DGV之前的一个断点工作,我看到提供了一个有效的数据表:

在此处输入图片说明

When I don't load any data into column, I can see a proper ComboBox selection: 当我没有将任何数据加载到列中时,可以看到一个正确的ComboBox选择:

在此处输入图片说明

However, if I add data in the datasource for this column, I get cell formatting error (saying the value is not valid) and the value is shown as display member text: 但是,如果我在此列的数据源中添加数据,则会收到单元格格式错误(说该值无效),并且该值显示为显示成员文本:

在此处输入图片说明

The database column is not nullable (at this point always 1), and is INT. 数据库列不可为空(此时始终为1),并且为INT。 I even tried to CAST it, to be sure it's not mixed up ie as string: 我什至试图对其进行CAST,以确保它没有混淆,即作为字符串:

CAST(ColAlign as INT) as ColAlign

Still, I get the error and I have no more ideas what can be wrong, but ovbiously the 1 in the datatable is not the same as 1 in the database result set. 仍然,我得到了错误,并且我没有更多的想法可能出什么问题了,但是奇怪的是,数据表中的1与数据库结果集中的1不相同。 In past I had a problem with Int16 not matching INT, but Int32 always worked agaist INT in database. 过去,我遇到了一个问题,即Int16与INT不匹配,但是Int32在数据库中始终可以正常使用INT。 And even: 乃至:

CAST(1 as INT) as ColAlign

...doesn't work. ...不起作用。 By the way, I assign the data simply this way: 顺便说一下,我就是这样简单地分配数据的:

Me.dgList.DataSource = ds.Tables(0)

As usually, it has to be something really simple, what I'm missing. 通常,它必须非常简单,这是我所缺少的。 I would appreciate even hints how to furthermore debug such an issue. 我什至希望获得进一步调试此类问题的提示。

EDIT: 编辑:

I also tried creating a button and in onClick wrote a code: 我也尝试创建一个按钮,并在onClick中编写了一个代码:

Me.dgList.Rows(1).Cells("ColAlign").Value = 1

This works well. 这很好。

EDIT 2: 编辑2:

I inserted a DataTable between DataSet and DataSource with fixed datatypes columns (int32 in case of the ComboBoxColumns), which should rule out that wrong datatypes are provided and it still doesn't work... 我在具有固定数据类型列的数据集和数据源之间插入了一个数据表(在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

EDIT 3 编辑3

Another debugging: 另一个调试:

    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)

dtTemp in DataSet Visualizer looks good and everything checked in MsgBox is es expected (ValueMember = "ID", DisplayMember = "Text", DataPropertyName = "ColAlign", Value = 2 /I set it to 2 for a change/). DataSet Visualizer中的dtTemp看起来不错,并且在MsgBox中检查的所有内容都是预期的(ValueMember =“ ID”,DisplayMember =“ Text”,DataPropertyName =“ ColAlign”,Value = 2 / I将其设置为2以进行更改/)。

WORKAROUND: 解决方法:

The only way it works is to leave columns with ComboBoxCell empty and fill them manually after the DGV datasource is set, narrowing them to Int32 along (note that they were narrowed both in SQL and dtGrid already): 唯一可行的方法是将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

Since I'm using DGV with ComboBoxCell extremely rarely, I can live with this "solution". 由于我很少将DGV与ComboBoxCell一起使用,因此我可以接受这种“解决方案”。

EDIT 4 / WORKAROUND 2 编辑4 /解决方法2

I created a 2nd, identical (structure) dtGrid2 and copied values row-by-row and cell-by-cell into the 2nd and voila - it works with the dtGrid2 and doesn't with the original dtGrid! 我创建了第二个相同的(结构)dtGrid2,并将值逐行和逐个单元地复制到第二个中, 这与dtGrid2一起使用 ,而不与原始dtGrid一起使用! So when I pull data from database, the original correct datatypes of columns are re-typed to something wrong. 因此,当我从数据库中提取数据时,列的原始正确数据类型被重新键入错误。 I suspect this is only happening with SQLiteDataAdapter, because I didn't experienced it with SqlDataAdapter in past. 我怀疑这仅发生在SQLiteDataAdapter上,因为我过去从未在SqlDataAdapter上经历过。 A simplified code to explain: 简化代码说明:

    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...

Try this: 尝试这个:

Dim cola As DataGridViewComboBoxColumn = CType(Me.dgList.Columns("ColAlign"), DataGridViewComboBoxColumn)
cola.DataSource = dtAlign  
cola.DataPropertyName = "ID"
cola.DisplayMember = "Text"
cola.ValueMember = "ID"

You need to set DataPropertyName if you are binding to DataSource like DataTable 如果要绑定到DataTable之类的DataSource,则需要设置DataPropertyName

You have a DataGridView with some columns set. 您有一个设置了一些列的DataGridView。
Something like this: 像这样:

在此处输入图片说明

But could be anything else. 但可能还有其他。
Let's create a sample DataSource using a List(Of Class ): 让我们使用List(Of Class )创建一个示例数据源:

Public Class MyDataSourceRow

    Private _ID As Integer
    Private _Text As String

    Public Sub New()

    End Sub

    Public Property ID() As Integer
        Get
            Return Me._ID
        End Get
        Set(ByVal value As Integer)
            Me._ID = value
        End Set
    End Property

    Public Property Text() As String
        Get
            Return Me._Text
        End Get
        Set(ByVal value As String)
            Me._Text = value
        End Set
    End Property

End Class


Creeate a new DataGridViewComboBoxColumn , set it's basic properties, specify a DataSource and add it to the DataGridView: 创建一个新的DataGridViewComboBoxColumn ,设置其基本属性,指定一个DataSource并将其添加到DataGridView中:

    Dim MyDataSource = New List(Of MyDataSourceRow)
    MyDataSource.Add(New MyDataSourceRow With {.ID = 1, .Text = "Left"})
    MyDataSource.Add(New MyDataSourceRow With {.ID = 2, .Text = "Right"})
    MyDataSource.Add(New MyDataSourceRow With {.ID = 3, .Text = "Center"})

    Dim MyColumn As DataGridViewComboBoxColumn = New DataGridViewComboBoxColumn
    MyColumn.Width = 150
    ' Name of the new Column. Will also be the text of the Header
    MyColumn.Name = "ComboAlignment"

    'Define its DataSource 
    MyColumn.DataSource = MyDataSource
    ' The DataPropertyName is the field of your DataSource to which your column value is bound
    MyColumn.DataPropertyName = "ID"
    ' This is the value you want the User to see
    MyColumn.DisplayMember = "Text"
    ' ValueMember is the value passed to the DataGrid when a User selects an entry in the DropDown
    MyColumn.ValueMember = "ID"

    'Insert the column in the first position -> Index(0)
    Me.DataGridView1.Columns.Insert(0, MyColumn)


Now, this is the result: 现在,这是结果:

在此处输入图片说明

For some reason, you are confusing the .Name of the column with it's .DataPropertyName 由于某种原因,您将列的.Name.DataPropertyName

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM