Help with validating data in DataGridView


How do I trigger  an error message if data entered in a cell is less then 5 characters or blank using VB.NET? I  need to force users to enter data in a column and in the right format.


Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

By using the CellValidating events:

Form1.vb -
Imports System.ComponentModel

Public Class Form1
	Private IsLoading As Boolean = False

	Private ReadOnly Products As BindingList(Of Product) = New BindingList(Of Product)() From
	  New Product() With {.ID = 1, .ProductName = "Milk", .Price = "2.34"},
	  New Product() With {.ID = 2, .ProductName = "Bread", .Price = "1.19"},
	  New Product() With {.ID = 3, .ProductName = "Eggs", .Price = "2.18"},
	  New Product() With {.ID = 4, .ProductName = "Butter", .Price = "3.14"},
	  New Product() With {.ID = 5, .ProductName = "Chips", .Price = "3.48"},
	  New Product() With {.ID = 6, .ProductName = "Salsa", .Price = "4.22"},
	  New Product() With {.ID = 7, .ProductName = "Bacon", .Price = "5.13"},
	  New Product() With {.ID = 8, .ProductName = "Sausage", .Price = "2.99"},
	  New Product() With {.ID = 9, .ProductName = "Peanut Butter", .Price = "2.56"},
	  New Product() With {.ID = 10, .ProductName = "Jelly", .Price = "2.99"}

	Private Sub OnLoad(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
		If Not IsLoading Then
			IsLoading = True
			DataGridSource.DataSource = Products
			DataGridView1.DataSource = DataGridSource
			IsLoading = False
		End If
	End Sub

	Private Sub OnCellValidating(ByVal sender As Object, ByVal e As DataGridViewCellValidatingEventArgs) Handles DataGridView1.CellValidating
		If Not IsLoading Then
			DataGridView1.Rows(e.RowIndex).ErrorText = ""

			If DataGridView1.Rows(e.RowIndex).IsNewRow Then Return

			If TypeOf DataGridView1.Columns(e.ColumnIndex) Is DataGridViewTextBoxColumn Then
				Dim tb As DataGridViewTextBoxColumn = DirectCast(DataGridView1.Columns(e.ColumnIndex), DataGridViewTextBoxColumn)

				If tb.Name.Equals(colQuantity.Name) Then
					Dim tempInteger As Integer

					If Not Integer.TryParse(e.FormattedValue.ToString(), tempInteger) Then
						e.Cancel = True
						DataGridView1.Rows(e.RowIndex).ErrorText = "The quantity must be an integer value."
					End If
				ElseIf tb.Name.Equals(colPrice.Name) Then
					Dim tempDecimal As Decimal

					If Not Decimal.TryParse(e.FormattedValue.ToString(), tempDecimal) OrElse tempDecimal < 0.0 Then
						e.Cancel = True
						DataGridView1.Rows(e.RowIndex).ErrorText = "The price must be a non-negative decimal value."
					End If
				End If
			End If
		End If
	End Sub

	Private Sub OnCellValidated(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValidated
		TextBox1.Text = Products.Sum(Function(item) item.SubTotal).ToString("C2")
	End Sub
End Class

Class Product
	Private fQuantity As Integer = 0
	Private fPrice As Decimal = 0.0
	Public Property ID() As Integer
	Public Property ProductName() As String

	Public Property Quantity() As Integer
			Return fQuantity
		End Get
		Set(ByVal value As Integer)
			If Not value.Equals(fQuantity) Then
				fQuantity = value
			End If
		End Set
	End Property

	Public Property Price() As Decimal
			Return fPrice
		End Get
		Set(ByVal value As Decimal)
			If Not value.Equals(fPrice) Then
				fPrice = value
			End If
		End Set
	End Property

	Public ReadOnly Property SubTotal() As Decimal
			Return Quantity * Price
		End Get
	End Property
End Class

Open in new window

Form1.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
	Inherits System.Windows.Forms.Form

	'Form overrides dispose to clean up the component list.
	<System.Diagnostics.DebuggerNonUserCode()> _
	Protected Overrides Sub Dispose(ByVal disposing As Boolean)
			If disposing AndAlso components IsNot Nothing Then
			End If
		End Try
	End Sub

	'Required by the Windows Form Designer
	Private components As System.ComponentModel.IContainer

	'NOTE: The following procedure is required by the Windows Form Designer
	'It can be modified using the Windows Form Designer.  
	'Do not modify it using the code editor.
	<System.Diagnostics.DebuggerStepThrough()> _
	Private Sub InitializeComponent()
		Me.components = New System.ComponentModel.Container()
		Me.DataGridView1 = New System.Windows.Forms.DataGridView()
		Me.colID = New System.Windows.Forms.DataGridViewTextBoxColumn()
		Me.colProductName = New System.Windows.Forms.DataGridViewTextBoxColumn()
		Me.colQuantity = New System.Windows.Forms.DataGridViewTextBoxColumn()
		Me.colPrice = New System.Windows.Forms.DataGridViewTextBoxColumn()
		Me.colSubTotal = New System.Windows.Forms.DataGridViewTextBoxColumn()
		Me.ProductSource = New System.Windows.Forms.BindingSource(Me.components)
		Me.Label1 = New System.Windows.Forms.Label()
		Me.TextBox1 = New System.Windows.Forms.TextBox()
		Me.DataGridSource = New System.Windows.Forms.BindingSource(Me.components)
		CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).BeginInit()
		CType(Me.ProductSource, System.ComponentModel.ISupportInitialize).BeginInit()
		CType(Me.DataGridSource, System.ComponentModel.ISupportInitialize).BeginInit()
		Me.DataGridView1.AllowUserToAddRows = False
		Me.DataGridView1.AllowUserToDeleteRows = False
		Me.DataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
		Me.DataGridView1.Columns.AddRange(New System.Windows.Forms.DataGridViewColumn() {Me.colID, Me.colProductName, Me.colQuantity, Me.colPrice, Me.colSubTotal})
		Me.DataGridView1.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnEnter
		Me.DataGridView1.Location = New System.Drawing.Point(13, 13)
		Me.DataGridView1.Name = "DataGridView1"
		Me.DataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect
		Me.DataGridView1.Size = New System.Drawing.Size(566, 214)
		Me.DataGridView1.TabIndex = 0
		Me.colID.DataPropertyName = "ID"
		Me.colID.HeaderText = "ID"
		Me.colID.Name = "colID"
		Me.colID.Visible = False
		Me.colProductName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill
		Me.colProductName.DataPropertyName = "ProductName"
		Me.colProductName.HeaderText = "Product Name"
		Me.colProductName.Name = "colProductName"
		Me.colProductName.ReadOnly = True
		Me.colProductName.Resizable = System.Windows.Forms.DataGridViewTriState.[True]
		Me.colProductName.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable
		Me.colQuantity.DataPropertyName = "Quantity"
		Me.colQuantity.HeaderText = "Quantity"
		Me.colQuantity.Name = "colQuantity"
		Me.colPrice.DataPropertyName = "Price"
		Me.colPrice.HeaderText = "Price"
		Me.colPrice.Name = "colPrice"
		Me.colSubTotal.DataPropertyName = "SubTotal"
		Me.colSubTotal.HeaderText = "SubTotal"
		Me.colSubTotal.Name = "colSubTotal"
		Me.colSubTotal.ReadOnly = True
		Me.Label1.AutoSize = True
		Me.Label1.Location = New System.Drawing.Point(434, 236)
		Me.Label1.Name = "Label1"
		Me.Label1.Size = New System.Drawing.Size(34, 13)
		Me.Label1.TabIndex = 1
		Me.Label1.Text = "Total:"
		Me.TextBox1.Location = New System.Drawing.Point(479, 233)
		Me.TextBox1.Name = "TextBox1"
		Me.TextBox1.ReadOnly = True
		Me.TextBox1.Size = New System.Drawing.Size(100, 20)
		Me.TextBox1.TabIndex = 2
		Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
		Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
		Me.ClientSize = New System.Drawing.Size(591, 265)
		Me.Name = "Form1"
		Me.Text = "Form1"
		CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).EndInit()
		CType(Me.ProductSource, System.ComponentModel.ISupportInitialize).EndInit()
		CType(Me.DataGridSource, System.ComponentModel.ISupportInitialize).EndInit()

	End Sub
	Friend WithEvents DataGridView1 As System.Windows.Forms.DataGridView
	Friend WithEvents Label1 As System.Windows.Forms.Label
	Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
	Friend WithEvents DataGridSource As System.Windows.Forms.BindingSource
	Friend WithEvents ProductSource As System.Windows.Forms.BindingSource
	Friend WithEvents colID As System.Windows.Forms.DataGridViewTextBoxColumn
	Friend WithEvents colProductName As System.Windows.Forms.DataGridViewTextBoxColumn
	Friend WithEvents colQuantity As System.Windows.Forms.DataGridViewTextBoxColumn
	Friend WithEvents colPrice As System.Windows.Forms.DataGridViewTextBoxColumn
	Friend WithEvents colSubTotal As System.Windows.Forms.DataGridViewTextBoxColumn

End Class

Open in new window

Which produces the following output -Initial startup state.Entering a null, empty or invalid quantity results in a row error being displayed and the user cannot go onto the next cell until the cell they are editing is valid.-saige-
Fernando SotoRetiredCommented:
The DataGridView control has a couple of events to handle this The first is the CellValidating event which happens when the user attempts to move away from the cell giving you the chance to make sure that the data the user entered is correct. The other is the CellValidated event which happens when CellValidating passes which will allow you to do any additional processing before continuing.

DataGridView.CellValidating Event
DataGridView.CellValidated Event

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
vcharlesAuthor Commented:
Thank you for the comments, will test the codes and get back to you.
Fernando SotoRetiredCommented:
Hi Victor;

Have you completed testing?
vcharlesAuthor Commented:
Thank You.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.