0

我有一个带有 DataGridView 的项目,它显示来自平面文件数据库的数据。有 7 个按钮可将 SQL 查询结果加载到 DGV,并添加一个复选框以选择行。

当用户选择一个复选框时,该特定 DataGridViewRow (DGVR) 将被添加到临时 List(Of DGVR) 以供以后使用。

然后有一个显示第二个表单的最终按钮,对选定的两个条目进行比较,将临时列表传递给第二个表单。

用户将能够从 2 个不同的选项中选择 1 个(因此有单独的列表)。

问题是,如果您单击按钮 1 并选择一行,当您单击第二个按钮时,将数据源重置为新查询结果的行显然会将所有现有 DGVR 转换为空指针。

IE:对 DGVR 的引用丢失。

如果您从第一个按钮中选择一个,然后从第二个按钮中选择一个,然后尝试传递两个选定的项目,第一个将为空,但第二个不会。

代码:

    Dim con As New OleDb.OleDbConnection
    Dim dbProvider As String
    Dim dbSource As String

    currentWeapon = "Sniper"

    Dim ds As New DataSet
    Dim da As New OleDb.OleDbDataAdapter
    Dim sql As String

    dbProvider = "PROVIDER=Microsoft.ACE.OLEDB.12.0;"
    dbSource = "Data Source = Resources/Battlefield 4 Weapons.accdb"
    con.ConnectionString = dbProvider & dbSource

    con.Open()

    sql = "SELECT * FROM [Battlefield 4 Weapons]"
    da = New OleDb.OleDbDataAdapter(sql, con)
    da.Fill(ds, "Battlefield 4 Weapons.accdb")

    con.Close()

    Dim dt As DataTable = ds.Tables(0)
    Dim dr As DataRow() = dt.Select("[Weapon type] = 'Sniper'", "Weapon Name")
    Dim miniDT As New DataTable

    miniDT = dr.CopyToDataTable()
    DataGridView1.DataSource = miniDT
    DataGridView1.Sort(DataGridView1.Columns("Weapon Name"), System.ComponentModel.ListSortDirection.Ascending)

    DataGridView1.MultiSelect = True

按下新按钮时使条目无效的行是以下行:

        DataGridView1.DataSource = miniDT

然后,当复选框被单击时,此代码运行(每种武器类型都有一个案例)。AsList 是设计用于在传递行之前临时保存行的列表:

    DataGridView1.EndEdit()
    Select Case currentWeapon
        Case "Assault"

            Assaultlabel.Visible = True
            AsList.RemoveRange(0, AsList.Count)
            For i = 0 To DataGridView1.Rows.Count - 1
                If DataGridView1.Rows(i).Cells(14).Value = True Then
                    If Not AsList.Contains(DataGridView1.Rows(i)) Then
                        AsList.Add(DataGridView1.Rows(i))
                    End If
                End If
            Next

我尝试克隆该行,以创建一个单独的副本,但这不起作用。如何将它与数据源分开,以便我可以加载一组新数据,但保存选定的行?

4

1 回答 1

1

每当DataSource更改时,DataGridView将删除所有行。您总是需要引用基础数据。我认为是时候了解DataTable如何绑定到网格了。

当您设置新数据源时,网格将查看新对象的类型是否实现了IListSource接口。DataTable实现了这个接口。它返回DefaultView并且它实际上是网格用作其源的这个实例。网格创建新行,每一行都绑定到DataRowView(反过来又绑定到DataRow)。

数据网格视图 > 数据视图 > 数据表

数据网格视图行 > 数据行视图 > 数据行

您可以通过DataGridViewRow的DataBoundItem属性获取对DataRowView的引用:

Dim gridRow As DataGridViewRow = Me.DataGridView1.Rows(0)
Dim viewRow As DataRowView = DirectCast(gridRow.DataBoundItem, DataRowView)
Dim tableRow As DataRow = viewRow.Row

无需复制数据表,只需创建一个新的数据视图:

Dim view1 As New DataView(mytable)
Dim view2 As New DataView(mytable)

您可以对数据视图进行排序和过滤。

view1.Sort = "Name ASC"
view1.RowFilter = "Name = 'Smith' And Age >= 18"

现在您可以将此 DataView用作数据源而不是默认视图。

Me.DataGridView1.DataSource = view1
于 2014-08-31T08:59:19.220 回答