When you databind your DataGridView to a List.

Like this.

First I create a class Person so I can bind to that. Watch the default constructor, it needs to make new elements, if that is what you want.

Public Class Person
    Private _name As String

    Public Sub New()
        _name = "person1"
    End Sub

    Public Sub New(ByVal Name As String)
        _name = Name
    End Sub

    Public Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property
End Class

Then the DataGridView.

''' <summary>
''' 
''' </summary>
''' <remarks></remarks>
Public Class PersonsGrid
    Inherits DataGridView

#Region "Fields"

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <remarks></remarks>
    Private WithEvents _BindingSource As New BindingSource()
    Dim _persons As New List(Of Person)

#End Region 'Fields

#Region "Constructors"

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()
        _persons.Add(New Person("Test1"))
        _persons.Add(New Person("Test2"))
        _persons.Add(New Person("Test3"))
        Me.BindToList()
    End Sub

#End Region 'Constructors

#Region "Methods" 'Methods

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub BindToList()
        _BindingSource.DataSource = _persons
        Me.DataSource = _BindingSource
        _BindingSource.AllowNew = True
    End Sub

#End Region 'Methods
    
End Class

You can smack that onto a form to see the result.

Then you can conditionally format rows by using the DataBindingComplete event, like this.

vbnet Private Sub PersonsGrid_DataBindingComplete(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewBindingCompleteEventArgs) Handles Me.DataBindingComplete For Each row As DataGridViewRow In Me.Rows If Not row.IsNewRow Then row.ReadOnly = True End If Next End Sub The above will make each row in the datagridview readonly except the new row (you know, the one with the * in front of it).

Or this.

vbnet ''' <summary> ''' ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub PersonsGrid_DataBindingComplete(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewBindingCompleteEventArgs) Handles Me.DataBindingComplete For Each row As DataGridViewRow In Me.Rows If Not row.IsNewRow Then row.DefaultCellStyle.BackColor = Color.Red End If Next End Sub Which will make the backcolor of each cell go red except the new row one.

And I did that because it is visually appealing 😉

Or this.

vbnet ''' <summary> ''' ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> ''' <remarks></remarks> Private Sub PersonsGrid_DataBindingComplete(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewBindingCompleteEventArgs) Handles Me.DataBindingComplete For Each row As DataGridViewRow In Me.Rows If row.Cells(0).Value IsNot Nothing Then If Not row.Cells(0).Value.ToString = "Test2" Then row.DefaultCellStyle.BackColor = Color.Red End If End If Next End Sub To make every row go red except the one with “Test2” in it.