Link to home
Start Free TrialLog in
Avatar of TSFLLC
TSFLLC

asked on

Leave Event Error (System.NullReferenceException: Object reference not set to an instance of an object.)

I'm trying to use a textbox.Leave event and execute a piece of code.  The error I get only happens in one situation.  Also, I've never had this type of error box display before.

I've included:
1) The error I am getting.
2) Default setup code of a text box I wish to leave and execute code.
3) txtPaymentAmount.Leave function
4) cmboProperty_SelectedIndexChange. The function that is executed prior to the leave event.

If I do not execute the cmboProperty_SelectedIndexChanged code, I can change the text in txtPaymentAmount with no error.  If I do click on a record from the dropdown of cmboProperty, I set focus to txtPaymentAmount...and when I change the text value, it errs.  The cmbo box function sets the text for several other cmbo boxes and then populates a datagrid by setting .RowFilter.

I am stumped as to what the problem could be.  Should I be using Validating/Validated or is using Leave the appropiate event for this function.  Once txtPaymentAmount is entered I am updating a field on the datagrid invoices until paymentamount is drawned down to 0 like what is done in Quickbooks.


1)
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
   at ASSNHOME.PaymentRegister.txtPaymentAmount_Leave(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnLeave(EventArgs e)
   at System.Windows.Forms.Control.NotifyLeave()
   at System.Windows.Forms.ContainerControl.UpdateFocusedControl()


2)
        '
        ' txtPaymentAmount
        '
        Me.txtPaymentAmount.BackColor = System.Drawing.SystemColors.Control
        Me.txtPaymentAmount.Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, System.Drawing.FontStyle.Regular,
                  System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.txtPaymentAmount.Location = New System.Drawing.Point(545, 50)
        Me.txtPaymentAmount.Name = "txtPaymentAmount"
        Me.txtPaymentAmount.Size = New System.Drawing.Size(115, 20)
        Me.txtPaymentAmount.TabIndex = 201
        Me.txtPaymentAmount.Text = ""

3)
    Private Sub txtPaymentAmount_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtPaymentAmount.Leave
        If Not IsNumeric(txtPaymentAmount.Text) Then
            Beep()
            MsgBox("NOT A VALID PAYMENT AMOUNT!!")
            txtPaymentAmount.Text = 0
            txtPaymentAmount.Focus()
            Exit Sub
        Else
            Dim i As Int32 = 0
            Dim xPaymentAmount As Double = txtPaymentAmount.Text
            Dim drv As DataRowView
            While i <= dvInvoice.Count - 1 And xPaymentAmount > 0
                Select Case drv(i)("invoice_balance")
                    Case Is = xPaymentAmount
                        drv = dvInvoice(i)
                        drv.BeginEdit()
                        drv("payment_amount") = xPaymentAmount
                        drv.EndEdit()
                        xPaymentAmount = 0
                    Case Is < xPaymentAmount
                    Case Is > xPaymentAmount
                End Select
                i += 1
            End While
        End If
    End Sub

4)
    Private Sub cmboProperty_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmboProperty.SelectedIndexChanged
        If Activating Then Exit Sub
        If cmboProperty.SelectedIndex > 0 Then
            Dim drv As DataRowView = dvProperties(cmboProperty.SelectedIndex)
            cmboSubdivision.SelectedValue = drv("subdivision_id").ToString
            cmboContact.SelectedValue = drv("contact_id").ToString
            cmboStreet.SelectedValue = drv("property_id").ToString
            txtPropertyID.Text = drv("property_id").ToString
            PopulateInvoices(drv("property_id").ToString, drv("contact_id").ToString)
            txtPaymentAmount.Focus()
        Else
            cmdClearNew_Click(Nothing, Nothing)
        End If
        Activating = False
    End Sub

5)
    Private Sub PopulateInvoices(ByVal xPropertyID As Int64, ByVal xContactID As Int64)
        dvInvoice.RowFilter = "property_id = " & xPropertyID & " AND contact_id = " & xContactID
    End Sub
ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of TSFLLC
TSFLLC

ASKER

Bob,

The changes worked!

But, what made you make the determination to change from a select case statement to an if statement, and why a single instead of double?
Should I be using Single datatypes for ALL temporary money fields?

After reviewing your code I also just realized that I was trying to dim xPaymentAmount as a double without getting the value of txtPaymentAmount.Text.

Thanks much!
Avatar of TSFLLC

ASKER

Bob,

I just found a posting where Fernando wrote regarding changing Action Solution Configuration would affect the Breakpoint.  That is why my debug was not working.  It was set to Release, not Debug.  Just the same, I would have had issue with this code.

Thanks!
Select Case blocks are, IMHO, good for strict case matching (0, 1, 2, 3, ... or "A", "B", "C").  The logic that you had was more of an If...Then statement, and doesn't lend itself very well to a Select Case.  

Actually, the internal working data type for floating numbers in the .NET framework is Decimal.  You can choose Single, Double, or Decimal interchangeably, as long as you are working with currency and not worried about the accuracy of the floating point.   Choosing data type is nitpicking in this case, but if you want to stick with a type, use Decimal.

Bob