我有一个带有DataGridView的项目,显示来自平面文件数据库的数据。有7个按钮可以将SQL查询结果加载到DGV,并添加一个复选框来选择行。
当用户选中一个复选框时,该特定的DataGridViewRow(DGVR)会被添加到临时列表(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
我已尝试克隆该行,创建一个独立的副本,但这并不起作用。如何将其与数据源分开,以便我可以加载一组新数据,但保存所选行?
答案 0 :(得分:1)
每次更改 DataSource 时,DataGridView都会删除所有行。您始终需要引用基础数据。我认为是时候了解DataTable如何绑定到网格。
当您设置新数据源时,网格将查看新对象的类型是否实现IListSource接口。 DataTable实现此接口。它返回DefaultView,它实际上就是网格用作源的实例。网格创建新行,每行绑定到DataRowView(后者又绑定到DataRow)。
DataGridView> DataView>数据表
DataGridViewRow> DataRowView>的DataRow
您可以通过DataRowView的DataBoundItem属性获取对DataGridViewRow的引用:
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"
现在您可以使用 this DataView作为数据源,而不是默认视图。
Me.DataGridView1.DataSource = view1