Hello,
One way to achieve this is to setup the DataGridView with a DataSource using a BindingList and BindingSource and subscribe to DataSourceChanged event of the BindingSource.
Full source
In the example below the following class represents the container for displaying, adding, editing and deleting in the DataGridView. Note INotifyPropertyChanged provides the ability for the DataGridView to be notified of changes and reflect this visually. The code in Person class may seem like a lot but it's worth the effort.
Container
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Public Class Person
Implements INotifyPropertyChanged
Private _firstName As String
Private _lastName As String
Private _personId As Integer
Public Property PersonId() As Integer
Get
Return _personId
End Get
Set
_personId = Value
OnPropertyChanged()
End Set
End Property
Public Property FirstName() As String
Get
Return _firstName
End Get
Set
_firstName = Value
OnPropertyChanged()
End Set
End Property
Public Property LastName() As String
Get
Return _lastName
End Get
Set
_lastName = Value
OnPropertyChanged()
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Protected Overridable Sub OnPropertyChanged(
<CallerMemberName> Optional memberName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(memberName))
End Sub
Public Overrides Function ToString() As String
Return $"{PersonId} {FirstName} {LastName}"
End Function
End Class
Load
Here I use mocked data
Public Class DataOperations
Public Shared Function LoadPeople() As List(Of Person)
Return New List(Of Person) From {
New Person() With {.PersonId = 1, .FirstName = "Karen", .LastName = "Payne"},
New Person() With {.PersonId = 2, .FirstName = "Bill", .LastName = "Miller"},
New Person() With {.PersonId = 3, .FirstName = "Anne", .LastName = "Adams"}}
End Function
End Class
Form code
Here DataSourceChanged is fired when personBindList = New BindingList(Of Person)(peopleList) is called. I check for FirstName equal to Karen and change it.
Imports System.ComponentModel
Public Class Form1
Private personBindList As New BindingList(Of Person)
WithEvents personBindingSource As New BindingSource
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
PeopleDataGridView.AutoGenerateColumns = False
Dim peopleList = DataOperations.LoadPeople()
personBindList = New BindingList(Of Person)(peopleList)
personBindingSource.DataSource = personBindList
PeopleDataGridView.DataSource = personBindingSource
End Sub
Private Sub personBindingSource_DataSourceChanged(sender As Object, e As EventArgs) _
Handles personBindingSource.DataSourceChanged
For index As Integer = 0 To personBindList.Count - 1
If personBindList(index).FirstName = "Karen" Then
personBindList(index).FirstName = "Karen 1"
End If
Next
End Sub
End Class
In closing
If you are using a DataTable as the DataSource for the BindingSource the above will still work without the Person class as DataSourceChanged event will still be triggered.