Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

Windows Forms DataGrid validation

Hi,
I'm using VB.NET 2005 Express, and I want to create a price break DataGrid having three columns, with an unknown number of rows.

In column 0, I want "From"
In column 1, I want "To"
In column 2, I want "Price"
That bit is easy enough.

The complicated bit, for me, is applying a min and max to the "From" and "To" cells. So, for example, if the user has entered ...

From|To|Price
1|9|5.00

... on the first row, when the user comes to add the next row, I want the "From" cell on the new row to only accept a value greater than 9, so the table may look like ...

From|To|Price
1|9|5.00
10|20|4.50

Any help would be greatly appreciated.
[721 byte] By [jellyfish5000] at [2007-11-11 10:13:50]
# 1 Re: Windows Forms DataGrid validation
Is the DataGrid bound to a data source? What kind of data source is it (database table, array, etc.)?
Phil Weber at 2007-11-11 20:48:20 >
# 2 Re: Windows Forms DataGrid validation
Yes, its bound to an Access database.
jellyfish5000 at 2007-11-11 20:49:31 >
# 3 Re: Windows Forms DataGrid validation
OK, assuming you're binding a Windows Forms DataGrid to an Access table named "Table", using a DataSet named "DataSet1," you need to add a method to handle the DataTable's ColumnChanging event:

' Add this line to your Form_Load event
AddHandler DataSet1.Tables("Table").ColumnChanging, _
AddressOf Table_ColumnChanging

Private Sub Table_ColumnChanging(ByVal sender As Object, _
ByVal e As System.Data.DataColumnChangeEventArgs)

Dim PreviousToValue As Integer = 0
Dim RowIndex As Integer = DataGrid1.CurrentRowIndex
' If not first row of grid...
If RowIndex > 0 Then
' Get value of second column of previous row
PreviousToValue = CInt(DataSet1.Tables("Table").Rows(RowIndex - 1).Item(1))
End If

If (e.Column.ColumnName.Equals("From")) Then
If CType(e.ProposedValue, Integer) <= PreviousToValue Then
e.Row.RowError = "The From column contains an error"
e.Row.SetColumnError(e.Column, "From value must be greater than To value of previous row.")
Else
e.Row.ClearErrors()
End If
End If
End Sub
Phil Weber at 2007-11-11 20:50:24 >
# 4 Re: Windows Forms DataGrid validation
This is excellent - exactly what I was looking for.
Thank you.
jellyfish5000 at 2007-11-11 20:51:29 >
# 5 Re: Windows Forms DataGrid validation
Using a variation of the above code, I'm struggling to add an additional feature to the grid, i.e. how do I ensure that 'To' value is greater than the 'From' value on the same row?

I tried to adjust the RowIndex bit:
PreviousToValue = CInt(DataSet1.Tables("Table").Rows(RowIndex - 1).Item(TO_COLUMN))
To be:
PreviousFromValue = CInt(DataSet1.Tables("Table").Rows(RowIndex).Item(FROM_COLUMN))
But this gives me indexing errors.

What am I doing wrong?
jellyfish5000 at 2007-11-11 20:52:34 >
# 6 Re: Windows Forms DataGrid validation
What is the value of FROM_COLUMN?
Phil Weber at 2007-11-11 20:53:28 >
# 7 Re: Windows Forms DataGrid validation
Its a CONST, which is 2.
The actual Access table comprises the following fields:
PriceBreakID (Autonumber)
ProductID
UnitOfMeasurementFrom
UnitOfMeasurementTo
UnitPrice

What I'm displaying in the grid is just the From, To, Unit Price
jellyfish5000 at 2007-11-11 20:54:32 >
# 8 Re: Windows Forms DataGrid validation
If "From" is the first column in the grid, shouldn't FROM_COLUMN = 0?
Phil Weber at 2007-11-11 20:55:31 >
# 9 Re: Windows Forms DataGrid validation
OK, this code seems to work for the first row, but throws an IndexOutOfRangeException for subsequent rows:

Private Const FROM_COLUMN As Integer = 0
Private Const TO_COLUMN As Integer = 1
Private Const PRICE_COLUMN As Integer = 2

Private Sub Table_ColumnChanging(ByVal sender As Object, _
ByVal e As System.Data.DataColumnChangeEventArgs)

Dim PreviousToValue As Integer = 0
Dim RowIndex As Integer = DataGrid1.CurrentRowIndex
' If not first row of grid...
If RowIndex > 0 Then
' Get value of second column of previous row
PreviousToValue = CInt(DataSet1.Tables("Table").Rows(RowIndex - 1).Item(TO_COLUMN))
End If

Select Case e.Column.Ordinal
Case FROM_COLUMN
If CType(e.ProposedValue, Integer) <= PreviousToValue Then
e.Row.RowError = "The From column contains an error"
e.Row.SetColumnError(e.Column, "From value must be greater than To value of previous row.")
Else
e.Row.RowError = ""
e.Row.SetColumnError(e.Column, "")
End If
Case TO_COLUMN
Dim FromValue As Integer = CInt(DataSet1.Tables("Table").Rows(RowIndex).Item(FROM_COLUMN))
If CType(e.ProposedValue, Integer) <= FromValue Then
e.Row.RowError = "The To column contains an error"
e.Row.SetColumnError(e.Column, "To value must be greater than From value.")
Else
e.Row.RowError = ""
e.Row.SetColumnError(e.Column, "")
End If
End Select
End Sub

Try this:

Private Sub Table_ColumnChanging(ByVal sender As Object, _
ByVal e As System.Data.DataColumnChangeEventArgs)

' Remember From column value between method calls
Static FromValue As Integer

Dim PreviousToValue As Integer = 0
Dim RowIndex As Integer = DataGrid1.CurrentRowIndex
' If not first row of grid...
If RowIndex > 0 Then
' Get value of second column of previous row
PreviousToValue = CInt(DataSet1.Tables("Table").Rows(RowIndex - 1).Item(TO_COLUMN))
End If

Select Case e.Column.Ordinal
Case FROM_COLUMN
If CType(e.ProposedValue, Integer) <= PreviousToValue Then
e.Row.RowError = "The From column contains an error"
e.Row.SetColumnError(e.Column, "From value must be greater than To value of previous row.")
Else
e.Row.RowError = ""
e.Row.SetColumnError(e.Column, "")
End If
' Save From value for To column validation below
FromValue = CType(e.ProposedValue, Integer)
Case TO_COLUMN
If CType(e.ProposedValue, Integer) <= FromValue Then
e.Row.RowError = "The To column contains an error"
e.Row.SetColumnError(e.Column, "To value must be greater than From value.")
Else
e.Row.RowError = ""
e.Row.SetColumnError(e.Column, "")
End If
End Select
End Sub
Phil Weber at 2007-11-11 20:56:28 >
# 10 Re: Windows Forms DataGrid validation
Thanks, Phil. This is perfect.
I must have spent about 2 hours playing with this yesterday evening!!
jellyfish5000 at 2007-11-11 20:57:35 >