datagridview 值从另一个 datagridview 中删除

datagridview values remove from another datagridview

我有两个数据网格视图。一个是 dtgridPopulate 并填充了数据库中的数据。

dtgridPopulate 列是(复选框、代码、名称)

checkbox code name
checkbox icon c1 customer_one

然后第二个datagridview 是dtgridGenerate,它从dtgridPopulate 生成值。 我使用代码 dtgridPopulate.Rows.Add(code, name) 手动将值从 dtgridPopulate 添加到 dtgridGenerate。

dtgridGenerate columns are (code, name)

code name
c1 customer_one

当我选中 dtgridPopulate 中的复选框时,它会将值(代码、名称)传输到 dtgridGenerate。但问题是当我取消选中 dtgridPopulate 中的复选框时,它还应该 REMOVE dtgridGenerate 中的值。

        Private Sub dtgridPopulateSelectAll_CurrentCellDirtyStateChanged(ByVal sender As Object, ByVal e As EventArgs) Handles dtgridPopulate.CurrentCellDirtyStateChanged

        RemoveHandler dtgridPopulate.CurrentCellDirtyStateChanged, AddressOf dtgridPopulateSelectAll_CurrentCellDirtyStateChanged

        If TypeOf dtgridPopulate.CurrentCell Is DataGridViewCheckBoxCell Then
            dtgridPopulate.EndEdit()
            Dim Checked As Boolean = CType(dtgridPopulate.CurrentCell.Value, Boolean)
            If Checked Then
                code = dtgridPopulate.CurrentRow.Cells(1).Value.ToString
                name = dtgridPopulate.CurrentRow.Cells(2).Value.ToString
                dtgridGenerate.Rows.Add(code, name)
            Else
               For Each drow As DataGridViewRow In dtgridPopulate.SelectedRows 'This is for uncheck but it doens't work
                    dtgridGenerate.Rows.Remove(row)
                Next
            End If
        End If

        AddHandler dtgridPopulate.CurrentCellDirtyStateChanged, AddressOf dtgridPopulateSelectAll_CurrentCellDirtyStateChanged
    End Sub

我参考这个

取消选中复选框时出错:提供的行不属于此 datagridview 控件。参数名称:datagridviewrow

我不确定您“为什么”退订然后 re-subscribed 参加活动。通常,仅当事件中的代码“更改”网格中会导致事件 re-fire 的某些内容时才需要这样做,而这在您当前的代码中没有发生。也不需要结束网格编辑。

此外,您对网格 CurrentCellDirtyStateChanged 事件的使用在您想要执行的操作方面有一个缺点……它不会 re-fire 如果用户一遍又一遍地选中和取消选中同一个单元格.换句话说,如果用户单击一个复选框单元格并且复选框被选中并且事件触发......然后......如果用户在点击任何其他单元格之前“取消选中”相同的单元格,那么该事件将不会重新触发。

此外,该事件似乎使用了与事件签名不同的网格……dtgridPopulateSelectAll_CurrentCellDirtyStateChanged……? ……“SelectAll”,事件中的网格被称为……dtgridPopulate……这令人困惑。

鉴于此,我建议有两件事可以提供帮助。 1)为第二个网格创建并使用“空”DataTable。这样我们就可以简单地从 table 添加和删除项目。 2) 为此使用 grids CellContnetClick 事件。它会 re-fire 如果用户一遍又一遍地单击同一个单元格,并且仅在更改复选框时才触发。

所以,我提出了这些小改动。首先在第二个格子中添加一个名为generateDT作为DataTable用作DataSource的全局变量。最初这个 table 是空的。其次使用网格 CellContentClick 事件来添加和删除行。

Dim generateDT As DataTable

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  Dim dt As DataTable = New DataTable()
  dt.Columns.Add("checkbox", GetType(Boolean))
  dt.Columns.Add("code", GetType(String))
  dt.Columns.Add("Name", GetType(String))
  dt.Rows.Add(False, "c1", "customer 1")
  dt.Rows.Add(False, "c2", "customer 2")
  dt.Rows.Add(False, "c3", "customer 3")
  dtgridPopulate.DataSource = dt
  generateDT = New DataTable()
  generateDT.Columns.Add("code", GetType(String))
  generateDT.Columns.Add("Name", GetType(String))
  dtgridGenerate.DataSource = generateDT
End Sub

然后在单元格内容的点击事件中,如果被点击的单元格是复选框单元格,那么...抓取选中状态以及clicked-on的codename排。然后,如果选中复选框单元格,则只需将 codename 添加到第二个网格全局 DataTable 变量 generateDT。如果未选中该复选框,那么我们将循环遍历第二个网格中的每一行,如果我们找到匹配项,则只需从第二个网格中删除该行全局 DataTable... 类似于...

Private Sub dtgridPopulate_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles dtgridPopulate.CellContentClick
  If e.ColumnIndex = 0 Then
    Dim Checked = CType(dtgridPopulate.Rows(e.RowIndex).Cells(e.ColumnIndex).EditedFormattedValue, Boolean)
    Dim code = dtgridPopulate.CurrentRow.Cells(1).Value.ToString
    Dim Name = dtgridPopulate.CurrentRow.Cells(2).Value.ToString
    If Checked Then
      generateDT.Rows.Add(code, Name)
    Else
      Dim rowToRemove As DataRowView
      For Each row As DataGridViewRow In dtgridGenerate.Rows
        If row.Cells(0).Value.ToString() = code Then
          rowToRemove = CType(row.DataBoundItem, DataRowView)
          generateDT.Rows.Remove(rowToRemove.Row)
          Exit For
        End If
     Next
    End If
  End If
End Sub