locked
Why is Textbox Validating Event Fired Twice? RRS feed

  • Question

  • I'm trying to figure out why my textbox called tbxDiscountUnit validating event fires when I programmatically set focus the textbox in the event.  I know what you're think..."why are you setting focus the textbox in the validating event, just set e.Cancel = True, and focus will be returned."  Here is the reason why I want to set focus the textbox in the validating event.  I only want to validate the textbox when the user has entered something in the textbox and leaves OR when its parent (usercontrol DiscountAdderRow) is validating.  When the DiscountAdderRow validating event is fired I call the tbxDiscountUnit validating event.  If the textbox text isn't valid I want to set focus the textbox and select all the text for the user to correct.   You can see this in my code.

    For some reason, when I include "Me.tbxDiscountUnit.Focus()" in the tbxDiscountUnit_Validating event the event fires twice, but when I remove the line of code it only fires once, why?

    Additionally, 

    Public Class DiscountAdderRow
    
        Private Sub tbxDiscountUnit_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles tbxDiscountUnit.Validating
    
            Try
                If Me.rbnFixed.Checked Then
                    Try
                        ' tbxDiscountUnit only needs to be validated when the user inputs something other than white space or DiscountAdderRow is validated
                        If (sender.Equals(Me.tbxDiscountUnit) And Not String.IsNullOrEmpty(Trim(Me.tbxDiscountUnit.Text))) Or sender.Equals(Me) Then
                            FormatCurrency(Me.tbxDiscountUnit.Text)
                        End If
                    Catch ex As InvalidCastException
                        MsgBox("The Discount Amount must be proper currency in this format  $#,###.##", MsgBoxStyle.Critical)
                        e.Cancel = True
                        Me.tbxDiscountUnit.Focus()
                        Me.tbxDiscountUnit.SelectAll()
                    End Try
                End If
    
                If Me.rbnPercent.Checked Then
                    Try
                        ' tbxDiscountUnit only needs to be validated when the user inputs something other than white space or DiscountAdderRow is validated
                        If (sender.Equals(Me.tbxDiscountUnit) And Not String.IsNullOrEmpty(Trim(Me.tbxDiscountUnit.Text))) Or sender.Equals(Me) Then
                            FormatPercent(Double.Parse(Me.tbxDiscountUnit.Text.Replace("%", "")) / 100, Globalization.NumberStyles.Number)
                        End If
                    Catch ex As FormatException
                        MsgBox("The Discount Amount must be proper percentage in this format  ##.#%", MsgBoxStyle.Critical)
                        e.Cancel = True
                        Me.tbxDiscountUnit.Focus()
                        Me.tbxDiscountUnit.SelectAll()
                    End Try
                End If
    
            Catch ex As Exception
                Call PublicProcedures.AppErrorHandler(Me.GetType.Name, System.Reflection.MethodBase.GetCurrentMethod().Name, ex)
                e.Cancel = True
            End Try
    
        End Sub
    
        Private Sub DiscountAdderRow_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.Validating
            If String.IsNullOrEmpty(Trim(Me.tbxDescription.Text)) Then
                MsgBox("You must enter a description.")
                e.Cancel = True
                Exit Sub
            End If
            Me.tbxDiscountUnit_Validating(sender, e)
        End Sub
    
        Private Sub DiscountAdderRow_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Validated
            Me.lblLastModifiedDate.Text = Now.ToString
            Me.lklLastModifiedUser.Text = My.Settings.UserFullName
        End Sub
    End Class


    Ryan


    • Edited by Ryan0827 Thursday, January 9, 2014 3:57 AM
    Thursday, January 9, 2014 3:55 AM

Answers

  • I'm trying to figure out why my textbox called tbxDiscountUnit validating event fires when I programmatically set focus the textbox in the event.

    That's not a good idea.

    Based on this MSDN document:

    "Do not attempt to set focus from within the Enter, GotFocus, Leave, LostFocus, Validating, or Validated event handlers. Doing so can cause your application or the operating system to stop responding."


    Please call me Frank :)

    • Marked as answer by Ryan0827 Wednesday, January 15, 2014 6:06 PM
    Wednesday, January 15, 2014 5:49 PM

All replies

  • For some reason, when I include "Me.tbxDiscountUnit.Focus()" in the tbxDiscountUnit_Validating event the event fires twice, but when I remove the line of code it only fires once, why?

    Change your code so that you can distinguish between an event raised by the user changing the focus, and an event raised by your code changing the focus.

    Static IsValidating As Boolean = False
    If Not IsValidating Then

      Processing = True
       ...
      Processing = False

    End Sub

    • Proposed as answer by Carl Cai Wednesday, January 15, 2014 6:52 AM
    Thursday, January 9, 2014 4:36 AM
  • Thanks Acamar for the reply.  Your suggestion seems to be a work around, but I'd like to understand why the validating event is being called twice?

    Ryan

    Wednesday, January 15, 2014 4:36 PM
  • I'm trying to figure out why my textbox called tbxDiscountUnit validating event fires when I programmatically set focus the textbox in the event.

    That's not a good idea.

    Based on this MSDN document:

    "Do not attempt to set focus from within the Enter, GotFocus, Leave, LostFocus, Validating, or Validated event handlers. Doing so can cause your application or the operating system to stop responding."


    Please call me Frank :)

    • Marked as answer by Ryan0827 Wednesday, January 15, 2014 6:06 PM
    Wednesday, January 15, 2014 5:49 PM
  • I would have given the same reply as Acamar.

    The events in the windows forms control simply have an order in which they always will be called by actions. 

    http://msdn.microsoft.com/en-us/library/86faxx0d(v=vs.110).aspx

    so when you do focus the focus event is given followed by the others among one the validationg even. 


    Success
    Cor


    • Edited by Cor Ligthert Wednesday, January 15, 2014 6:24 PM
    Wednesday, January 15, 2014 6:24 PM