Implementing my own FormatException on Datagridview bound to typed dataset. RRS feed

  • Question

  • I have created a simple project which I hope illustrates my problem.

    I have created a table in a test database

    CREATE TABLE [dbo].[tblTest](
    	[TEST_ID] [bigint] IDENTITY(1,1) NOT NULL,
    	[TEST_INT] [int] NOT NULL,
    	[TEST_STRING] [nvarchar](10) NULL

    I have created a test windows form project, added a dataset (named TEST_VALIDATIONDataSet) and added the tblTest table to the dataset.

    I then added a datagridview to the form. I have the following code in the form which just loads the datatable and binds it to the datagrid.

    Public Class Form1
     Dim DT As New TEST_VALIDATIONDataSet.tblTestDataTable
     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      Dim TA As New TEST_VALIDATIONDataSetTableAdapters.tblTestTableAdapter
      Dim BS As New BindingSource
      BS.DataSource = DT
      DataGridView1.DataSource = BS
     End Sub
     Private Sub DataGridView1_DataError(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles DataGridView1.DataError
      'I can intercept e.Exception here and throw my own exception but in order to change the column name I think I would need to parse the e.Exception.Message 
      'In any case I don't think this logic should be in the presentation layer, I think it should be in Partial Class TEST_VALIDATIONDataSet where the other validation is. 
     End Sub
    End Class

    When the form loads, if I enter a string into the TEST_INT column of the datagrid a FormatException "Input string was not in the correct format" is raised. I would like to be able to display an alternative error message for example "Column TEST_INT is an integer column and you have entered a string value" Actually, this is not the error I want to raise but it illustrates all the data I want available to me i.e. the column name and the column data type (if possible) and what type of validation error has occured.

    I have tried to add some validation logic to the a class tblTestDataTable using a partial class:

    Partial Class TEST_VALIDATIONDataSet
        Partial Class tblTestDataTable

            Private Sub tblTestDataTable_ColumnChanging(ByVal sender As Object, ByVal e As System.Data.DataColumnChangeEventArgs) Handles Me.ColumnChanging
                'This event fires as long as the data entered is valid according to the database table schema so I could add some business logic here:

                If e.Column.ColumnName = Me.TEST_INTColumn.ColumnName Then
                    If Not e.ProposedValue Is DBNull.Value AndAlso e.ProposedValue > 10 Then
                        Throw New ApplicationException("[tblTestDataTable_ColumnChanging] This column cannot be set to more than 10")
                    End If
                End If
            End Sub

            Private Sub tblTestDataTable_tblTestRowChanging(ByVal sender As Object, ByVal e As tblTestRowChangeEvent) Handles Me.tblTestRowChanging
                'This event fires as long as the data is valid according to the database table schema so I could have my business validation here

                If e.Row.TEST_INT > 10 Then
                    Throw New ApplicationException("[tblTestDataTable_tblTestRowChanging] This column cannot be set to more than 10")
                End If

            End Sub

        End Class

    End Class

    this works upto a point ie.e as long as the data is valid, I can perform some validation, but the FormatException occurs before these events are fired.

    I also have a similar problem which can be reproduced by [not entering] any data into the TEST_INT column and then entering a valid string 'XXX' into the TEST_STRING column and clicking onto the next row (or tabbing out of the TEST_STRING cell)

    A NoNullAllowedException "Column 'TEST_INT' does not allow nulls" is raised which again, I cannot intercept before it is raised.

    Can anyone suggest a "best practice" way that I can keep my validation logic in my DataTable and be able to replace both of these erros with my own?

    I could just add validation to the CellValidating and RowValidating events on the datagridview but that doesn't encapsulate the business logic in the tblTestDataTable which I want to do so I can reuse this object on different forms.


    • Edited by Ben Buck Thursday, June 3, 2010 9:36 PM spotted an error in the example code
    Wednesday, June 2, 2010 7:18 PM


All replies