vb.netwinformsbindingsourcedatagridviewrowbindingnavigator

DataGridView is not showing first row after removing other rows


I am having a problem that I have been debugging for some days.

Some context, I have an application where I store the data (in the following code a list of class Expediente) in xml files using serialization. For displaying the data I deserialize it and then I create a datatable which I use as the datasource for the datagrid. I added a datagridcheckbox column to check the ones to delete.

In the datagrid I have a toolstrip button that when clicked it removes the checked -or checked in edit mode thus the line CType(dgvr.Cells(0).GetEditedFormattedValue(dgvr.Index, DataGridViewDataErrorContexts.Commit), Boolean) = True- elements from the datasource and persists the datasource to an xml.

The problem is that when deserializing the xml and loading it again to a datatable and binding the datagrid datasource to it, it removes the first row. If I close the application and open it, the first row appears.

I have debuged and in the datatable the correct numbers of rows appear. Moreover, I have narrowed the problem to the binding navigator, when it sets its binding source to the datable there the first row of the datagrid disappears.

I paste a simplified version of the code, I can provide more if needed. Note that if in LoadGridExpedientes() I comment the lines

navExpedientes.BindingSource = Nothing

navExpedientes.BindingSource = bs

The first row doesn't disappear but obviously the counter of the binding navigator does not update.

 Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim chk As New DataGridViewCheckBoxColumn()
    grdExpedientes.Columns.Add(chk)
    chk.HeaderText = ""
    chk.Name = "chk"
    'fills a datatable from an xml, it works ok, it fills it with the correct amount of rows
    Dim dt As DataTable = Sistema.getInstance.getDataExpedienteForGrid()
    Dim bs As New BindingSource
    bs.DataSource = dt

    grdExpedientes.DataSource = bs
    navExpedientes.BindingSource = bs

    For i As Integer = 0 To grdExpedientes.Rows.Count - 2
        grdExpedientes.Rows(i).Cells(0).Value = True
    Next        
End Sub

Private Sub LoadGridExpedientes()        
        grdExpedientes.DataSource = Nothing
        navExpedientes.BindingSource = Nothing
        grdExpedientes.Columns.Clear()
        grdExpedientes.Rows.Clear()
        'This is to know if there is already the checkbox column
        If Not (grdExpedientes.Columns.Count > 0 AndAlso grdExpedientes.Columns(0).Name = "chk") Then
            Dim chk As New DataGridViewCheckBoxColumn()
            grdExpedientes.Columns.Add(chk)
            chk.HeaderText = ""
            chk.Name = "chk"
        End If
        Dim dt As DataTable = Sistema.getInstance.getDataExpedienteForGrid()
        Dim bs As New BindingSource
        bs.DataSource = dt
        grdExpedientes.DataSource = bs
        navExpedientes.BindingSource = bs
    End Sub

Private Sub navExpedientesDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles navExpedientesDelete.Click
        For i As Integer = 0 To grdExpedientes.Rows.Count - 2
            Dim dgvr As DataGridViewRow = grdExpedientes.Rows(i)
            If CType(dgvr.Cells(0).Value, Boolean) = True Or _
              CType(dgvr.Cells(0).GetEditedFormattedValue(dgvr.Index, DataGridViewDataErrorContexts.Commit), Boolean) = True Then
                Dim draux As DataGridViewRow = dgvr
                Dim expABorrar As Expediente = CType((From elem As Expediente In Sistema.listExpedientes
                                             Where elem.Expediente = CType(draux.Cells("Expediente (Ficha)").Value, String)
                                             Select elem).FirstOrDefault, Expediente)
                Sistema.listExpedientes.Remove(expABorrar)
            End If
        Next
        If System.IO.File.Exists(Sistema.pathListExpedientes) Then
            System.IO.File.Delete(Sistema.pathListExpedientes)
        End If
        Dim sw As System.IO.TextWriter = New System.IO.StreamWriter(Sistema.rutaListaExpedientes, 0)
        Serializer(Of Expediente).Serialize(Sistema.listExpedientes, sw, New List(Of Type) From {GetType(Movimiento)})
        sw.Close()
        LoadGridExpedientes()
    End Sub

Solution

  • The problem was that I was using the delete toolstrip button that comes with the binding navigator, it seems that when clicked it has 'embedded' that it deletes the row that was selected that by default is the first one.

    I created a new toolstrip button in the binding navigator and the problem was solved. I do not know why not updating the binding navigator binding source also avoided the first row from being removed.