Home > OS >  datagridview values remove from another datagridview
datagridview values remove from another datagridview

Time:05-20

I have two datagridviews. One is dtgridPopulate and is populated with data from the database.

dtgridPopulate columns are (checkbox, code, name)

checkbox code name
checkbox icon c1 customer_one

Then the second datagridview is dtgridGenerate which has generated values from dtgridPopulate. I use the code dtgridPopulate.Rows.Add(code, name) to add manually the value from dtgridPopulate to dtgridGenerate.

dtgridGenerate columns are (code, name)

code name
c1 customer_one

When I check the checkbox in the dtgridPopulate it will transfer the values (code, name) to the dtgridGenerate. But the problem is when I uncheck the checkbox in the dtgridPopulate, It should also REMOVE the values in the 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

I refer to this reference

Error when I uncheck the checkbox: row provided does not belong to this datagridview control. parameter name: datagridviewrow

CodePudding user response:

I am not sure “why” you have unsubscribed and then re-subscribed to the event. Typically, this is only needed if the code in the event “changes” something in the grid that would cause the event to re-fire and this is not happening in your current code. Nor is ending the grids edit necessary.

Also, your use of the grids CurrentCellDirtyStateChanged event has one drawback in relation to what you want to do… it will NOT re-fire if the user checks and unchecks the same cell over and over. In other words, if the user clicks a check box cell and the check box becomes checked and the event fires… then … if the user “unchecks” the same cell before clicking on any other cell, then the event will NOT refire.

Also, it looks like the event is using a different grid from the signature of the event… dtgridPopulateSelectAll_CurrentCellDirtyStateChanged … ? … “SelectAll” and the grid in the event is called… dtgridPopulate … this is confusing.

Given this, I suggest two things to help. 1) create and use an “Empty” DataTable for the second grid. This way we could simply add and remove items from that table. 2) use the grids CellContnetClick event for this. It will re-fire if the user clicks on the same cell over and over in addition to firing ONLY when the check box is changed.

So, I propose these small changes. First add a global variable named generateDT as a DataTable used as a DataSource to the second grid. Initially this table would be empty. Second use the grids CellContentClick event to make these additions and removal of the rows.

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

Then in the cell content click event, if the clicked cell is a check box cell, then… grab the checked state and both the code and name of the clicked-on row. Then if the check box cell is checked, then simply add the code and name to the second grids global DataTable variable generateDT. If the check box is unchecked, then we will loop through each row in the second grid and if we find a match then simply remove that row from the second grids global DataTable… something like…

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
  • Related