PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197

PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197

PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197

PHP User Warning: fetch_template() calls should be replaced by the vB_Template class. Template name: bbcode_highlight in ..../includes/functions.php on line 4197
Proper way to use Validating event-VBForums
Results 1 to 18 of 18

Thread: Proper way to use Validating event

  1. #1

    Thread Starter
    Addicted Member kutlesh's Avatar
    Join Date
    Jun 2018
    Location
    Skopje, Macedonia
    Posts
    195

    Proper way to use Validating event

    I was working on old VB6 apps, and yes there were validating events which couldn't even allow the user to close the application using the "X" button at the top of the window.

    Though VB.NET also has a "validating" event I am still not sure how is to be used properly because I don't want to confuse the user of my application by locking the application at just the currently selected field if the validation fails

    Can you recommend me some good examples or tutorials for using validating event in VB.NET?

  2. #2
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    104,755

    Re: Proper way to use Validating event

    It's simple stuff. Handle the Validating event and set e.Cancel to True if validation fails to prevent the control losing focus. Before using the data, call ValidateChildren to ensure that even controls that haven't received focus are validated. Provide a Cancel Button and set its CausesValidation property to False so that clicking it will not cause the previous control to be validated. That allows you to close the form while it contains invalid data.

  3. #3

    Thread Starter
    Addicted Member kutlesh's Avatar
    Join Date
    Jun 2018
    Location
    Skopje, Macedonia
    Posts
    195

    Re: Proper way to use Validating event

    What do you mean by Cancel button? Show message box with Ok/Cancel buttons?

    Also validating event doesn't get called if I set CausesValidation to false. Do I miss something?

    Made a sample code but still the form gets stuck if CausesValidation is true

    Code:
    Private Sub denMTB_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles denMTB.Validating
            Dim den As Integer = Convert.ToInt32(denMTB.Text)
    
            If den < 1 Or den > 31 Then
                e.Cancel = True
                MsgBox("Внеси ден од 1 до 31!", MsgBoxStyle.OkCancel)
            Else
                ValidateChildren()
                SendKeys.Send("{TAB}")
            End If
        End Sub
    By the way, ValidateChildren() throw an exception

    Code:
    Process is terminated due to StackOverflowException.
    EDIT:

    I modified some of the code like so:

    Code:
    Private Sub denMTB_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles denMTB.Validating
            Dim den As Integer = Convert.ToInt32(denMTB.Text)
    
            If den < 1 Or den > 31 Then
                e.Cancel = True
    
                If MsgBox("Внеси ден од 1 до 31!", MsgBoxStyle.OkOnly) = MsgBoxResult.Ok Then
                    e.Cancel = False
                End If
            Else
                    'ValidateChildren()
                    SendKeys.Send("{TAB}")
            End If
        End Sub
    Last edited by kutlesh; Dec 19th, 2019 at 02:50 PM.

  4. #4
    PowerPoster i00's Avatar
    Join Date
    Mar 2002
    Location
    1/2 way accross the galaxy.. and then some
    Posts
    2,347

    Re: Proper way to use Validating event

    Quote Originally Posted by kutlesh View Post
    I modified some of the code like so:

    Code:
    Private Sub denMTB_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles denMTB.Validating
            Dim den As Integer = Convert.ToInt32(denMTB.Text)
    
            If den < 1 Or den > 31 Then
                e.Cancel = True
    
                If MsgBox("Внеси ден од 1 до 31!", MsgBoxStyle.OkOnly) = MsgBoxResult.Ok Then
                    e.Cancel = False
                End If
            Else
                    'ValidateChildren()
                    SendKeys.Send("{TAB}")
            End If
        End Sub
    Should prob look like this:
    VB.Net Code:
    1. Private Sub denMTB_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles denMTB.Validating
    2.         Dim den As Integer = Convert.ToInt32(denMTB.Text)
    3.         If den < 1 Or den > 31 Then
    4.             e.Cancel = True
    5.             MsgBox("Внеси ден од 1 до 31!", MsgBoxStyle.OkOnly)
    6.         End If
    7.     End Sub

    The e.cancel = True is pointless... since it will be set to false after... but judging by the message it should be cancel = True
    ... and SendKeys is just pure evil ... please expalin what you were trying to achieve with this

    ... also have you considered using a NumericUpDown?

    Kris

  5. #5
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    104,755

    Re: Proper way to use Validating event

    Quote Originally Posted by kutlesh View Post
    What do you mean by Cancel button? Show message box with Ok/Cancel buttons?
    Yes, that's what I mean. The OK Button means that the user is happy that all required data is present and all provided data is valid so you can go ahead and use it. The Cancel Button means that the user has decided against entering data so you can discard anything that has been entered and close the form.
    Quote Originally Posted by kutlesh View Post
    Also validating event doesn't get called if I set CausesValidation to false. Do I miss something?
    Of course it doesn't. That's the whole point. Did you bother reading the documentation for that property or doing any additional research? I'd wager not.

    The CausesValidation property is True by default for all WinForms controls. What that means is that, when any of those controls receive focus, the control that previously had focus will raise its Validating and, optionally, Validated events. If you set CausesValidation to False for a control, that means that the previous control will not be validated when that control receives focus. That's why you set that property to False on a Cancel Button specifically. It allows you to click the Button, thus focusing it, without validating the previous control. That means that you can close the form with that Button even if the previous control contains invalid data.
    Quote Originally Posted by kutlesh View Post
    By the way, ValidateChildren() throw an exception

    Code:
    Process is terminated due to StackOverflowException.
    Of course it did. The point of ValidateChildren is to raise the Validating and, optionally, Validated events on ALL child controls. If you do that in the Validating event handler then of course you're going to overflow the stack, because you raise the Validating event every time the Validating event is raised. You are supposed to call ValidateChildren when you're ready to use ALL the data, e.g. save it to a database. The point is to ensure that even controls that haven't received focus are validated. That would be primarily to ensure that all required data has been entered. If there's no chance of a control being invalid if it hasn't received focus then there's no need to call ValidateChildren. Again, if you read some documentation and did some research, you'd have a better understanding of how things are supposed to work.
    Quote Originally Posted by kutlesh View Post
    Code:
    Private Sub denMTB_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles denMTB.Validating
            Dim den As Integer = Convert.ToInt32(denMTB.Text)
    
            If den < 1 Or den > 31 Then
                e.Cancel = True
    
                If MsgBox("Внеси ден од 1 до 31!", MsgBoxStyle.OkOnly) = MsgBoxResult.Ok Then
                    e.Cancel = False
                End If
            Else
                    'ValidateChildren()
                    SendKeys.Send("{TAB}")
            End If
        End Sub
    What is that SendKeys call for? It looks like you're trying to shift focus to the next control in the Tab order but the current control is already losing focus if the Validating event has been raised, so another control is already receiving focus. Apart from that, if you actually did want to shift focus to the next control in the Tab order, the way to do that is by calling SelectNextControl.

    Here's what a well-implemented Validating event handler would look like:
    vb.net Code:
    1. Private Sub numberTextBox_Validating(sender As Object, e As CancelEventArgs) Handles numberTextBox.Validating
    2.     Dim number As Integer
    3.  
    4.     If Not Integer.TryParse(numberTextBox.Text, Nothing) OrElse
    5.        number < 1 OrElse
    6.        number > 31 Then
    7.         'Highlight all text and show highlight when not focused.
    8.         numberTextBox.SelectAll()
    9.         numberTextBox.HideSelection = False
    10.  
    11.         MessageBox.Show("Please enter a number in the range 1 to 31.",
    12.                         "invalid Data",
    13.                         MessageBoxButtons.OK,
    14.                         MessageBoxIcon.Exclamation)
    15.  
    16.         numberTextBox.HideSelection = True
    17.  
    18.         'Don't let the control lose focus.
    19.         e.Cancel = True
    20.     End If
    21. End Sub
    22.  
    23. Private Sub okButton_Click(sender As Object, e As EventArgs) Handles okButton.Click
    24.     'Ensure that all controls have been validated.
    25.     If ValidateChildren() Then
    26.         'All data is valid so it can be used safely here and the form closed.
    27.         '...
    28.         DialogResult = DialogResult.OK
    29.     End If
    30. End Sub
    31.  
    32. 'The Button is named "cancelOperationButton" so as not to clash with the form's "CancelButton" property.
    33. 'The Button's "CausesValidation" property would be set to "False" so it can be clicked without validating the previous control.
    34. Private Sub cancelOperationButton_Click(sender As Object, e As EventArgs) Handles cancelOperationButton.Click
    35.     'This whole event handler is not required if the Button's "DialogResult" property is set to "Cancel".
    36.     DialogResult = DialogResult.Cancel
    37. End Sub
    I'm suspicious about that numeric range though. It looks like you might be trying to select a day of the month. As suggested by i00, a NumericUpDown would like be better for entering numeric data, as it allows you to set a minimum and a maximum and it handles all the validation automatically. That said, mybe you should be using a DateTimePicker if you're working with a date, as it also handles validation and thus will not let you select a day that doesn't exist in a month, e.g. you can't select September 31 and you can't select February 29 except in a leap year.

  6. #6
    PowerPoster
    Join Date
    Sep 2005
    Location
    Modesto, Ca.
    Posts
    4,450

    Re: Proper way to use Validating event

    This doesn't seem right either,

    Code:
    Dim den As Integer = Convert.ToInt32(denMTB.Text)
    This will throw an error is someone enters non numeric value by mistake (or on purpose ).

    Use Integer.TryParse method,

    Code:
            Dim var As Integer
            If Integer.TryParse(TextBox1.Text, var) Then
                MessageBox.Show("It is an Integer")
            End If
    EDIT - jmc beat me to the punch.

  7. #7

    Thread Starter
    Addicted Member kutlesh's Avatar
    Join Date
    Jun 2018
    Location
    Skopje, Macedonia
    Posts
    195

    Re: Proper way to use Validating event

    Yes, I don't use Convert.ToInt32() since it throws exception in my actual application. I have built my own function that returns -1 if the conversion to positive integer fails or the actual number.

    I used Convert.ToInt32() because its on my home PC so that I don't think too much on conversion. It is an exercise application. Can change it anytime.

    @jmc yes its a day field. My exercise application consists of several fields, day, month, year of birth and the 6 left numbers of the person identification number. Then comes a combo box for choosing sex and then a field for place of living identification number.

    EDIT:

    The application is for fast data entry. For example we have a table with codes for different places in our country, so the application should search for a given code entered in a given text box and if it exists, jump to the next field in the form. That is why I use SendKeys.Send("{TAB}").

    There is a better way?
    Last edited by kutlesh; Dec 21st, 2019 at 01:40 PM.

  8. #8

    Thread Starter
    Addicted Member kutlesh's Avatar
    Join Date
    Jun 2018
    Location
    Skopje, Macedonia
    Posts
    195

    Re: Proper way to use Validating event

    Coded a form like this:

    Name:  Vezhba1.jpg
Views: 65
Size:  15.1 KB

    The day text field has CausesValidation set to true and here is the code behind:

    Code:
    Public Class Form4
        Private Sub MaskedTextBox1_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles MaskedTextBox1.Validating
            Dim number As Integer
    
            If Not Integer.TryParse(MaskedTextBox1.Text, number) OrElse
               number < 1 OrElse
               number > 31 Then
                'Highlight all text and show highlight when not focused.
                MaskedTextBox1.SelectAll()
                MaskedTextBox1.HideSelection = False
    
                MessageBox.Show("Please enter a number in the range 1 to 31.",
                                "invalid Data",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation)
    
                MaskedTextBox1.HideSelection = True
    
                'Don't let the control lose focus.
                e.Cancel = True
            End If
        End Sub
    
        Private Sub okButton_Click(sender As Object, e As EventArgs) Handles okButton.Click
            'Ensure that all controls have been validated.
            If ValidateChildren() Then
                'All data is valid so it can be used safely here and the form closed.
                '...
                DialogResult = DialogResult.OK
            End If
        End Sub
    
        Private Sub cancelOperationButton_Click(sender As Object, e As EventArgs) Handles cancelOperationButton.Click
            'This whole event handler is not required if the Button's "DialogResult" property is set to "Cancel".
            DialogResult = DialogResult.Cancel
        End Sub
    End Class
    Cannot close the form. Its stuck. And if I set CausesValidation to false on the day text field, nothing happens, not validation at all... hmm

    ValidateChildren() doesn't makes a call to that MaskedTextBox1_Validating() event...
    Last edited by kutlesh; Dec 21st, 2019 at 01:54 PM.

  9. #9
    PowerPoster
    Join Date
    Sep 2005
    Location
    Modesto, Ca.
    Posts
    4,450

    Re: Proper way to use Validating event

    Are you talking about the form not closing when you click the okButton or the cancelOperationButton. What is the purpose of the cancelOperationButton? Also is there a valid number in the MTB.

  10. #10

    Thread Starter
    Addicted Member kutlesh's Avatar
    Join Date
    Jun 2018
    Location
    Skopje, Macedonia
    Posts
    195

    Re: Proper way to use Validating event

    Yes, pressing cancel or OK won't allow closing the form. Also form "X" button fires validating and doesn't allow me to close the form.
    Only when I input value in the required range, I can close the form

    That DialogResult thing doesn't change much

    Should the MessageBox be of type OkCancel and then add some custom logic to those two buttons, Ok and Cancel?
    Last edited by kutlesh; Dec 21st, 2019 at 03:14 PM.

  11. #11
    PowerPoster
    Join Date
    Sep 2005
    Location
    Modesto, Ca.
    Posts
    4,450

    Re: Proper way to use Validating event

    If you want to exit without a valid entry then change to this,

    Code:
                If MessageBox.Show("Please enter a number in the range 1 to 31.",
                                "invalid Data",
                                MessageBoxButtons.OKCancel,
                                MessageBoxIcon.Exclamation) <> DialogResult.Cancel Then
                    'Don't let the control lose focus.
                    e.Cancel = True
                End If

  12. #12

    Thread Starter
    Addicted Member kutlesh's Avatar
    Join Date
    Jun 2018
    Location
    Skopje, Macedonia
    Posts
    195

    Re: Proper way to use Validating event

    Yes that does make a difference. And yes I guessed it right, the MessageBox should be of type OKCancel
    Now the bottom left "Cancel" button on the form seems unnecessary. Or is it?

  13. #13
    PowerPoster
    Join Date
    Sep 2005
    Location
    Modesto, Ca.
    Posts
    4,450

    Re: Proper way to use Validating event

    Neither button is necessary,

    Code:
        Private Sub Form6_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
            If ValidateChildren() Then
                DialogResult = DialogResult.Cancel
            Else
                e.Cancel = True
            End If
        End Sub
    But how you design it is up to you.

  14. #14

    Thread Starter
    Addicted Member kutlesh's Avatar
    Join Date
    Jun 2018
    Location
    Skopje, Macedonia
    Posts
    195

    Re: Proper way to use Validating event

    Lol, so tricky to make it work... why it shows the same MessageBox twice, one after the other?

    First validate event called when the field looses focus, and the second when called ValidateChildren() right?
    Yes that's true...

    Not sure why but, ValidateChildren() doesn't call the validate event when CausesValidation is set to false...

    Current code:

    Code:
    Public Class Form4
        Private Sub MaskedTextBox1_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles MaskedTextBox1.Validating
            Dim number As Integer
    
            If Not Integer.TryParse(MaskedTextBox1.Text, number) OrElse
               number < 1 OrElse
               number > 31 Then
                'Highlight all text and show highlight when not focused.
                MaskedTextBox1.SelectAll()
                MaskedTextBox1.HideSelection = False
    
                If MessageBox.Show("Please enter a number in the range 1 to 31.",
                                "invalid Data",
                                MessageBoxButtons.OKCancel,
                                MessageBoxIcon.Exclamation) <> DialogResult.Cancel Then
    
                    MaskedTextBox1.HideSelection = True
    
                    'Don't let the control lose focus.
                    e.Cancel = True
                End If
            End If
        End Sub
    
        Private Sub Form4_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
            If ValidateChildren() Then
                DialogResult = DialogResult.Cancel
            Else
                e.Cancel = True
            End If
        End Sub
    End Class
    Last edited by kutlesh; Dec 21st, 2019 at 03:47 PM.

  15. #15
    PowerPoster
    Join Date
    Sep 2005
    Location
    Modesto, Ca.
    Posts
    4,450

    Re: Proper way to use Validating event

    Not sure why but, ValidateChildren() doesn't call the validate event when CausesValidation is set to false...
    Why would it validate? You told it not to.

  16. #16

    Thread Starter
    Addicted Member kutlesh's Avatar
    Join Date
    Jun 2018
    Location
    Skopje, Macedonia
    Posts
    195

    Re: Proper way to use Validating event

    So how can I set the damn thing not to show the messagebox twice one after the other???
    Last edited by kutlesh; Dec 21st, 2019 at 03:55 PM.

  17. #17
    PowerPoster
    Join Date
    Sep 2005
    Location
    Modesto, Ca.
    Posts
    4,450

    Re: Proper way to use Validating event

    Code:
        Private Sub MaskedTextBox1_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles MaskedTextBox1.Validating
            Dim number As Integer
    
            If Not Integer.TryParse(MaskedTextBox1.Text, number) OrElse
               number < 1 OrElse
               number > 31 Then
                'Highlight all text and show highlight when not focused.
                MaskedTextBox1.SelectAll()
                MaskedTextBox1.HideSelection = False
    
                If MessageBox.Show("Please enter a number in the range 1 to 31.",
                                "invalid Data",
                                MessageBoxButtons.OKCancel,
                                MessageBoxIcon.Exclamation) <> DialogResult.Cancel Then
                    'Don't let the control lose focus.
                    e.Cancel = True
                Else
                    Me.MaskedTextBox1.CausesValidation = False
                End If
    
    
            End If
        End Sub
    If you want the focus set to a specific control if you press Cancel then just Select that control,

    Code:
        Private Sub MaskedTextBox1_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles MaskedTextBox1.Validating
            Dim number As Integer
    
            If Not Integer.TryParse(MaskedTextBox1.Text, number) OrElse
               number < 1 OrElse
               number > 31 Then
                'Highlight all text and show highlight when not focused.
                MaskedTextBox1.SelectAll()
                MaskedTextBox1.HideSelection = False
    
                If MessageBox.Show("Please enter a number in the range 1 to 31.",
                                "invalid Data",
                                MessageBoxButtons.OKCancel,
                                MessageBoxIcon.Exclamation) <> DialogResult.Cancel Then
                    'Don't let the control lose focus.
                    e.Cancel = True
                Else
                    Me.MaskedTextBox1.CausesValidation = False
                    Me.Button1.Select()
                End If
    
    
            End If
        End Sub
    Last edited by wes4dbt; Dec 21st, 2019 at 04:24 PM.

  18. #18
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    104,755

    Re: Proper way to use Validating event

    I posted the following in another thread but, because the topics - or my answers, at least - overlap somewhat, I will duplicate it here, for everyone's benefit. A major point to note is that CausesValidation actually works as I said but closing a form that was displayed using Show will still cause the Validating events to be raised. This doesn't happen when using ShowDialog, presumably because the form is not disposed when it is closed. That means that you need to detach event handlers manually in conjunction with using CausesValidation in order to display a form with Show and then close it while it contains invalid data.
    I just did some testing and it seems that CausesValidation works as I expected when the form is displayed by calling ShowDialog but not when calling Show. It must have something to do with when the form is disposed. Presumably you are calling Show. Is Show actually the better option or should it actually be ShowDialog? If you do need to use Show, you can still make it work if you attach and detach the Validating event handlers dynamically. Try creating a new WinForms project with two forms and have the first form create and display the second form. Add three TextBoxes and two Buttons to the second form and add this code:
    vb.net Code:
    1. Imports System.ComponentModel
    2.  
    3. Public Class Form1
    4.  
    5.     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6.         'Allow Button2 to be clicked without performing validation.
    7.         Button2.CausesValidation = False
    8.     End Sub
    9.  
    10.     Private Sub TextBox1_Validating(sender As Object, e As CancelEventArgs) Handles TextBox1.Validating
    11.         Dim number As Integer
    12.  
    13.         If Not Integer.TryParse(TextBox1.Text, number) OrElse number < 1 OrElse number > 100 Then
    14.             TextBox1.SelectAll()
    15.             TextBox1.HideSelection = False
    16.  
    17.             MessageBox.Show("TextBox1 must contain a whole number in the range 1 to 100",
    18.                             "Invalid Data",
    19.                             MessageBoxButtons.OK,
    20.                             MessageBoxIcon.Exclamation)
    21.  
    22.             TextBox1.HideSelection = False
    23.             e.Cancel = True
    24.         End If
    25.     End Sub
    26.  
    27.     Private Sub TextBox2_Validating(sender As Object, e As CancelEventArgs) Handles TextBox2.Validating
    28.         Dim [date] As Date
    29.  
    30.         If Not Date.TryParse(TextBox2.Text, [date]) OrElse [date] < #1/1/2000# OrElse [date].TimeOfDay <> TimeSpan.Zero Then
    31.             TextBox2.SelectAll()
    32.             TextBox2.HideSelection = False
    33.  
    34.             MessageBox.Show("TextBox2 must contain a round date no earlier than January 1, 2000",
    35.                             "Invalid Data",
    36.                             MessageBoxButtons.OK,
    37.                             MessageBoxIcon.Exclamation)
    38.  
    39.             TextBox2.HideSelection = False
    40.             e.Cancel = True
    41.         End If
    42.     End Sub
    43.  
    44.     Private Sub TextBox3_Validating(sender As Object, e As CancelEventArgs) Handles TextBox3.Validating
    45.         If TextBox3.TextLength = 0 OrElse Not TextBox3.Text.All(Function(ch) Char.IsLetter(ch)) Then
    46.             TextBox3.SelectAll()
    47.             TextBox3.HideSelection = False
    48.  
    49.             MessageBox.Show("TextBox3 must contain text that consists only of letters",
    50.                             "Invalid Data",
    51.                             MessageBoxButtons.OK,
    52.                             MessageBoxIcon.Exclamation)
    53.  
    54.             TextBox3.HideSelection = False
    55.             e.Cancel = True
    56.         End If
    57.     End Sub
    58.  
    59.     Private Sub TextBoxes_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown,
    60.                                                                                TextBox2.KeyDown,
    61.                                                                                TextBox3.KeyDown
    62.         Select Case e.KeyData
    63.             Case Keys.Enter
    64.                 'Move forward in the Tab order on Enter.
    65.                 SelectNextControl(DirectCast(sender, Control), True, True, True, True)
    66.  
    67.                 e.SuppressKeyPress = True
    68.             Case Keys.Shift Or Keys.Enter
    69.                 'Move backward in the Tab order on Shift+Enter.
    70.                 SelectNextControl(DirectCast(sender, Control), False, True, True, True)
    71.  
    72.                 e.SuppressKeyPress = True
    73.         End Select
    74.     End Sub
    75.  
    76.     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    77.         If ValidateChildren() Then
    78.             'Close the form when all data is valid.
    79.             MessageBox.Show("All data is valid. Closing form.")
    80.             Close()
    81.         Else
    82.             MessageBox.Show("Unable to close form with invalid data", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error)
    83.         End If
    84.     End Sub
    85.  
    86.     Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    87.         'Close the form whether data is valid or not.
    88.         Close()
    89.     End Sub
    90.  
    91. End Class
    If you display that second form using ShowDialog, you'll find that you can close the form by clicking Button2 even if the data is not valid. If you use Show rather than ShowDialog though, clicking Button2 won't close the form. If you change the code to this:
    vb.net Code:
    1. Imports System.ComponentModel
    2.  
    3. Public Class Form1
    4.  
    5.     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6.         'Allow Button2 to be clicked without performing validation.
    7.         Button2.CausesValidation = False
    8.  
    9.         'Attach Validating event handlers.
    10.         AddHandler TextBox1.Validating, AddressOf TextBox1_Validating
    11.         AddHandler TextBox2.Validating, AddressOf TextBox2_Validating
    12.         AddHandler TextBox3.Validating, AddressOf TextBox3_Validating
    13.     End Sub
    14.  
    15.     Private Sub TextBox1_Validating(sender As Object, e As CancelEventArgs)
    16.         Dim number As Integer
    17.  
    18.         If Not Integer.TryParse(TextBox1.Text, number) OrElse number < 1 OrElse number > 100 Then
    19.             TextBox1.SelectAll()
    20.             TextBox1.HideSelection = False
    21.  
    22.             MessageBox.Show("TextBox1 must contain a whole number in the range 1 to 100",
    23.                             "Invalid Data",
    24.                             MessageBoxButtons.OK,
    25.                             MessageBoxIcon.Exclamation)
    26.  
    27.             TextBox1.HideSelection = False
    28.             e.Cancel = True
    29.         End If
    30.     End Sub
    31.  
    32.     Private Sub TextBox2_Validating(sender As Object, e As CancelEventArgs)
    33.         Dim [date] As Date
    34.  
    35.         If Not Date.TryParse(TextBox2.Text, [date]) OrElse [date] < #1/1/2000# OrElse [date].TimeOfDay <> TimeSpan.Zero Then
    36.             TextBox2.SelectAll()
    37.             TextBox2.HideSelection = False
    38.  
    39.             MessageBox.Show("TextBox2 must contain a round date no earlier than January 1, 2000",
    40.                             "Invalid Data",
    41.                             MessageBoxButtons.OK,
    42.                             MessageBoxIcon.Exclamation)
    43.  
    44.             TextBox2.HideSelection = False
    45.             e.Cancel = True
    46.         End If
    47.     End Sub
    48.  
    49.     Private Sub TextBox3_Validating(sender As Object, e As CancelEventArgs)
    50.         If TextBox3.TextLength = 0 OrElse Not TextBox3.Text.All(Function(ch) Char.IsLetter(ch)) Then
    51.             TextBox3.SelectAll()
    52.             TextBox3.HideSelection = False
    53.  
    54.             MessageBox.Show("TextBox3 must contain text that consists only of letters",
    55.                             "Invalid Data",
    56.                             MessageBoxButtons.OK,
    57.                             MessageBoxIcon.Exclamation)
    58.  
    59.             TextBox3.HideSelection = False
    60.             e.Cancel = True
    61.         End If
    62.     End Sub
    63.  
    64.     Private Sub TextBoxes_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown,
    65.                                                                                TextBox2.KeyDown,
    66.                                                                                TextBox3.KeyDown
    67.         Select Case e.KeyData
    68.             Case Keys.Enter
    69.                 'Move forward in the Tab order on Enter.
    70.                 SelectNextControl(DirectCast(sender, Control), True, True, True, True)
    71.  
    72.                 e.SuppressKeyPress = True
    73.             Case Keys.Shift Or Keys.Enter
    74.                 'Move backward in the Tab order on Shift+Enter.
    75.                 SelectNextControl(DirectCast(sender, Control), False, True, True, True)
    76.  
    77.                 e.SuppressKeyPress = True
    78.         End Select
    79.     End Sub
    80.  
    81.     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    82.         If ValidateChildren() Then
    83.             'Close the form when all data is valid.
    84.             MessageBox.Show("All data is valid. Closing form.")
    85.             Close()
    86.         Else
    87.             MessageBox.Show("Unable to close form with invalid data", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error)
    88.         End If
    89.     End Sub
    90.  
    91.     Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    92.         'Detach Validating event handlers.
    93.         RemoveHandler TextBox1.Validating, AddressOf TextBox1_Validating
    94.         RemoveHandler TextBox2.Validating, AddressOf TextBox2_Validating
    95.         RemoveHandler TextBox3.Validating, AddressOf TextBox3_Validating
    96.  
    97.         'Close the form whether data is valid or not.
    98.         Close()
    99.     End Sub
    100.  
    101. End Class
    then you'll be able to close the form containing invalid data by clicking Button2, even if the form was displayed by calling Show.

    Note that this code also answers the question you asked here about advancing through the controls using the Enter key.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width