vb.netdatagridviewbindingsourcebindinglist

How to reset BindingSource/BindingList sequence number in DataGridView with VB.NET


I'm trying to reset BindingSource/BindingList sequence number in DataGridView with VB.NET.

or something went wrong in my code implementation

Please Guide Me.

Below I attach screenshots and codes as well

Thanks

Public Class Form1
    Private bindingSource As BindingSource = Nothing
    Private Function GetProduct() As Product
        Return If(DataGridView1.SelectedCells.Count = 0, Nothing, TryCast(DataGridView1.SelectedCells(0).OwningRow.DataBoundItem, Product))
    End Function
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim list = New List(Of Product)() From {
    New Product With {
        .No = 1,
        .Codeproduct = "1000",
        .Qty = 20,
        .Qty_Stock = 50
    },
    New Product With {
            .No = 2,
        .Codeproduct = "2000",
        .Qty = 30,
        .Qty_Stock = 40
    },
     New Product With {
            .No = 3,
        .Codeproduct = "3000",
        .Qty = 30,
        .Qty_Stock = 40
    }
}

 bindingSource = New BindingSource With {.DataSource = New BindingList(Of Product)(CType(list, IList(Of Product)))}
        DataGridView1.DataSource = bindingSource
        DataGridView1.Columns("No").ReadOnly = True
        DataGridView1.Columns("Codeproduct").ReadOnly = True
        DataGridView1.Columns("Qty").ReadOnly = True
        DataGridView1.Columns("Qty_Stock").ReadOnly = True
        DataGridView1.Columns("Coldel").ReadOnly = True
 End Sub

    Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
        If DataGridView1.Columns(e.ColumnIndex) Is DataGridView1.Columns("Coldel") Then
            If DataGridView1.SelectedRows.Count = 0 Then
                Return
            End If
            If MessageBox.Show("Delete selected record?", "CONFIRM!", MessageBoxButtons.YesNoCancel) = DialogResult.Yes Then
                Dim product = GetProduct()
                Dim bs = TryCast(bindingSource.DataSource, BindingList(Of Product))
                'do method service sql to database
                bs.Remove(product)
                DataGridView1.Refresh()

'update code 
  Dim counter As Integer = 0
                For Each row As DataGridViewRow In DataGridView1.Rows
                    counter += 1
                    'row.Cells("No").Value = counter
row.Cells("No").Value = If(row.Index = DataGridView1.NewRowIndex, Nothing, counter)
                Next row
                'do method service sql save to database




            End If
        End If
    End Sub
End Class

Before Delete No 2 enter image description here

after Delete No 2 enter image description here

So in the results want number 3 to be number 2

After update code

After update code-2


Solution

  • The new grid row displays the default value of the data-bound object. For reference types, the new row displays nothing if the value is nothing, or it displays the value of the column DefaultCellStyle.NullValue property if you want to provide a default value rather than Nothing/DbNull.

    For the value types like your No column, the data-bound item is of type Integer, so, the new row displays the default value of that type, 0. No, you can't use here the NullValue property to change that.

    To hide the default value 0 in the No column, you have two options. Either convert the property to nullable integer in the model:

    Public Class Product
        Public Property No As Integer?
        ' ...
    End Class
    

    Or set the DefaultCellStyle.Format property to hide the zero values. The # format specifier for example. See Custom numeric format strings for more.

    DataGridView1.Columns("No").DefaultCellStyle.Format = "#"
    

    Side Notes

    ▶ You can replace this:

    bindingSource = New BindingSource With {.DataSource = New BindingList(Of Product)(CType(list, IList(Of Product)))}
    

    With:

    bindingSource = New BindingSource(New BindingList(Of Product)(list), Nothing)
    

    ▶ You can simplify the CellContentClick event:

    Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
        Dim dgv = DirectCast(sender, DataGridView)
        If e.RowIndex >= 0 AndAlso
        dgv.Columns("ColDel") Is dgv.Columns(e.ColumnIndex) Then
            Dim item = TryCast(dgv.Rows(e.RowIndex).DataBoundItem, Product)
            If item IsNot Nothing AndAlso
                MessageBox.Show("Confirm ...", "App", MessageBoxButtons.YesNo) = DialogResult.Yes Then
                Dim i = 1
                Dim bs = DirectCast(dgv.DataSource, BindingSource)
                bs.Remove(item)
                For Each row As Product In bs
                    row.No = i
                    i += 1
                Next
            End If
        End If
    End Sub