【问题标题】:Set column datatype automatically自动设置列数据类型
【发布时间】:2016-05-10 20:57:24
【问题描述】:

我使用 csv 文件作为 datagridview 的数据源。它工作正常,显示数据,但是当我尝试对数字数据进行排序时,它排序为字符串(“9”>“10”)。

当我将数据行添加到 datagridview 时,我会这样做:

Dim data() As String = _textStreamReader.ReadLine.Split(vbTab)
dt.Rows.Add(data.ToArray)

我不想显式地一一添加列,以编程方式设置其数据类型,从而失去向源数据添加新列并将其加载到 datagridview 中的灵活性(新列和所有)。

有没有办法测试列中单元格的内容是否为数字并相应地设置列的数据类型?每列要么全部为文本,要么全部为浮点数。

【问题讨论】:

  • 如果您不想添加列并想坚持使用ToArray,那么不,我不知道测试的方法。如果您想进行预初始化,您始终可以进行各种数据转换测试以确定每个位置的内容,创建列,然后添加行。如果您进行预初始化测试,它将适用于新列。只需确保按照特定的优先顺序进行测试即可。
  • 在某些时候,某人或某事必须指定数据类型。编译器要么使用最低公分母(字符串),要么添加类型列,或者定义一个匹配的类并将数据解析为该类并使用 List 而不是数据表。顺便说一句,data 已经是一个数组了。
  • @ChrisFannin 这听起来可行。你有我可以参考的代码示例吗?
  • @Plutonix 可以在 addedColumn 事件上完成吗?
  • 是的,但它有什么不同呢?您要么有代码来添加一些类型化的列,要么有代码有条件地丢弃一些字符串列(基于顺序)并替换为硬编码的不同列类型。如果它不是用于数据库,请使用 List(of T);如果是去 db,从 db 表中获取 dt 列 defs。

标签: .net vb.net datagridview


【解决方案1】:

如果您想坚持阅读 CSV 并将其解析为 DataTable,这里有一个 hackish 方法。还有更优雅的方式,但您需要更改您的设计。

我的表单只有一个名为dgvDataGridView。这是代码隐藏的内容。 List(Of String()) 仅代表内存中的 CSV 文件。在您的情况下,您将第一个 ReadLine 结果传递给 AddDataColumns,然后将其添加到 dt.LoadDataRow,然后是后续行。

Public Class Form1

   Dim dt As DataTable = New DataTable()

   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

      Dim data As List(Of String()) = New List(Of String())
      data.Add(New String() {"test", "123", "12.3", "1/1/2000", "false"})
      data.Add(New String() {"test2", "456", "45.6", "2/2/2002", "true"})
      data.Add(New String() {"test3", "789", "78.9", "3/3/2003", "false"})
      data.Add(New String() {"test4", "012", "1.2", "4/4/2004", "true"})

      AddDataColumns(data(0))

      For Each line() As String In data
         dt.LoadDataRow(line, True)
      Next

      dgv.DataSource = dt

   End Sub

   Private Sub AddDataColumns(ByRef values() As String)

      Dim dc As DataColumn

      For Each value As String In values

         dc = New DataColumn()

         If Boolean.TryParse(value, Nothing) Then
            dc.DataType = GetType(Boolean)
            dc.Caption = "Boolean"

         ElseIf Integer.TryParse(value, Nothing) Then
            dc.DataType = GetType(Integer)
            dc.Caption = "Integer"

         ElseIf Long.TryParse(value, Nothing) Then
            dc.DataType = GetType(Long)
            dc.Caption = "Long"

         ElseIf Single.TryParse(value, Nothing) Then
            dc.DataType = GetType(Single)
            dc.Caption = "Single"

         ElseIf Double.TryParse(value, Nothing) Then
            dc.DataType = GetType(Double)
            dc.Caption = "Double"

         ElseIf Decimal.TryParse(value, Nothing) Then
            dc.DataType = GetType(Decimal)
            dc.Caption = "Decimal"

         ElseIf DateTime.TryParse(value, Nothing) Then
            dc.DataType = GetType(DateTime)
            dc.Caption = "DateTime"

         Else
            dc.DataType = GetType(String)
            dc.Caption = "String"

         End If

         dt.Columns.Add(dc)

      Next

   End Sub

End Class

结果:

【讨论】:

  • 如果您在dc.Caption 行下方的每个数据类型测试中添加Debug.Print,您可以看到它检测到的每个值是什么。示例:Debug.Print("Value: " & value & " = " & dc.Caption)
猜你喜欢
  • 2021-09-07
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
  • 2011-02-28
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
相关资源
最近更新 更多