【问题标题】:Visual Basic 2019: ArgumentException thrown when trying to add a row to a DataTableVisual Basic 2019:尝试将行添加到 DataTable 时引发 ArgumentException
【发布时间】:2019-12-13 09:56:43
【问题描述】:

我正在创建一个学生数据库,为了添加一个学生,我包含了一个单独的表单。单独的窗体调用主窗体中的子 AddStudent()。在 AddStudent() 子中,当我向表中添加一行时,我得到一个 ArgumentException,因为显然该表没有任何列。我在全局范围内创建了表,表的列是在由 Form1.Load 处理的 sub 中创建的。

Public Class Form1

Private HiddenPages As New List(Of TabPage)
Dim StudentDB As New DataTable

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    CreateTable()
    StudentDGV.DataSource = StudentDB
End Sub

Sub AddStudent(ByRef first As String, ByRef last As String, ByRef grade As String)
    StudentDB.Rows.Add(last, first, CInt(grade))
    StudentDGV.Refresh()
End Sub

Sub CreateTable()
    With StudentDB
        .Columns.Add("LastName", Type.GetType("System.String"))
        .Columns.Add("FirstName", Type.GetType("System.String"))
        .Columns.Add("GradeLevel", Type.GetType("System.Int16"))
    End With
End Sub

如果有必要,StudentDGV 就是 DataGridView。

你能帮我解决我的问题吗?

【问题讨论】:

  • StudentBS.DataSource = StudentDGV BindingSource 正在使用网格?告诉我们哪一行抛出异常总是有帮助的。您应该只需要设置一次 Source,而不是每次添加一行。
  • 我简化了@LarsTech,但我仍然得到一个 ArgumentException。
  • 发布的代码不会产生异常。您在谈论单独的表格。它们是如何相互引用的?

标签: vb.net datatable datasource


【解决方案1】:

单独的窗体调用主窗体中的子 AddStudent()。在 AddStudent() 子中,当我向表中添加一行时出现 ArgumentException,因为显然该表没有任何列。

我可以设想会产生这组条件的一个场景是,来自单独形式的调用在辅助线程上运行,并且调用的形式为:

Form1.AddStudent("lastname", "firstname", "integer as string")

其中Form1默认实例 属性。默认表单实例是特定于线程的。在从辅助线程引用默认表单实例时,将返回 Form1 的新实例。由于从未显示此实例,因此不会在此实例上调用 Form_Load 事件,因此不会在此实例上执行 CreateTable 方法。这就是StudentDB 没有任何列的原因。

如果上面的分析是正确的,那么你有几个问题需要处理。首先,您不应该使用辅助线程来显示此单独的表单。我建议一般不要使用默认实例。相反,您可以将此表单传递给要调用的委托,而不是回调主表单的 AddStudent 方法。


编辑:

我突然想到,上面的分析假设显示了Form1 的实例。如果您还没有显示,您也会遇到同样的问题。

【讨论】:

    【解决方案2】:

    您使用 Int16 类型定义了成绩列

    .Columns.Add("GradeLevel", Type.GetType("System.Int16"))
    

    然后你尝试添加一个 int32

    StudentDB.Rows.Add(last, first, CInt(grade))
    

    您可以将列更改为 int32 或将等级字符串转换为 int16。

    【讨论】:

      【解决方案3】:

      您需要NewRow() 方法。此外,这些方法参数没有理由应该是ByRef。将它们保留为默认的ByVal。请记住,ByVal 仍然通过引用;它只是传递引用的值(副本)。

      Sub AddStudent(first As String, last As String, grade As String)
          Dim row = StudentDB.NewRow()
          row["LastName"] = last
          row["FirstName"] = first
          row["GradeLevel"] = CInt(grade)
          StudentDB.Rows.Add(row)
      End Sub
      

      【讨论】:

      • 他并不“需要”NewRow()。 Rows.Add 确实有一个 ParamArray 重载。 NewRow 可能是首选。
      • 我仍然在 row("LastName") = last 行得到 ArgumentException
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      • 2016-02-26
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多