Changing textbox backgroud color with exception

bigboywasim

Member
Joined
Sep 29, 2006
Messages
18
Programming Experience
Beginner
VB.NET:
Option Strict On
Public Class Form1

    Private Sub btnCalculate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculate.Click

        Try
            If IsValidData() Then

                Dim MonthlyInvestment As Decimal = Convert.ToDecimal(txtInvestments.Text)
                Dim YearlyInterestRate As Decimal = Convert.ToDecimal(txtInterestRate.Text)
                Dim NumberofYears As Integer = Convert.ToInt32(txtYears.Text)

                Dim MonthlyInterestRate As Decimal = YearlyInterestRate / 12 / 100
                Dim Months As Integer = NumberofYears * 12
                Dim FutureValue As Decimal = Me.FutureValue(MonthlyInvestment, MonthlyInterestRate, Months)

                txtFutureValue.Text = FormatCurrency(FutureValue)
                txtInvestments.Select()
            End If


        Catch ex As Exception
            MessageBox.Show(ex.Message & vbNewLine & vbNewLine & ex.GetType.ToString & vbNewLine & vbNewLine & ex.StackTrace, "Exception")
        End Try


    End Sub

    Private Function FutureValue(ByVal MonthlyInvestment As Decimal, ByVal MonthlyInterestRate As Decimal, ByVal Months As Integer) As Decimal


        For i As Integer = 1 To Months
            FutureValue = (FutureValue + MonthlyInvestment) * (1 + MonthlyInterestRate)
        Next
        Return FutureValue

    End Function
    Private Function IsValidData() As Boolean
        Return _
        IsPresent(txtInvestments) AndAlso _
        ISDecimal(txtInvestments) AndAlso _
        InRange(txtInvestments, 1, 1000) AndAlso _
        IsPresent(txtInterestRate) AndAlso _
        ISDecimal(txtInterestRate) AndAlso _
        InRange(txtInterestRate, 1, 15) AndAlso _
        IsPresent(txtYears) AndAlso _
        IsInt32(txtYears) AndAlso _
        InRange(txtYears, 1, 50)

    End Function

    Private Function IsPresent(ByVal txtBox As TextBox) As Boolean
        If txtBox.Text = "" Then
            MessageBox.Show("Please do not leave the field blank, empty field error")
            txtBox.BackColor = Color.Red
            Return False
        Else
            Return True
        End If


    End Function
    Private Function ISDecimal(ByVal txtBox As TextBox) As Boolean
        Try
            Convert.ToDecimal(txtBox.Text)
            Return True
        Catch ex As FormatException
            MessageBox.Show("Entry must be a number, entry error")
            txtBox.Focus()
            txtBox.BackColor = Color.Red
            Return False
        End Try
    End Function
    Private Function IsInt32(ByVal txtBox As TextBox) As Boolean
        Try
            Convert.ToInt32(txtBox.Text)
            Return True
        Catch ex As FormatException
            MessageBox.Show(" Entry must be a Whole Number or Integer, no decimal, entry error")
            txtBox.Focus()
            txtBox.BackColor = Color.Red
            Return False
        End Try
    End Function
    Private Function InRange(ByVal txtBox As TextBox, ByVal Min As Decimal, ByVal Max As Decimal) _
    As Boolean
        Dim Number As Decimal = Convert.ToDecimal(txtBox.Text)

        If Number < Min OrElse Number > Max Then
            MessageBox.Show("Range error, Number must be" & "(" & Min & "-" & Max & ")")
            txtBox.Focus()
            txtBox.BackColor = Color.Red

            Return False
        Else
            Return True
        End If
    End Function


    Private Sub ClearFutureValue(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtInvestments.TextChanged, txtYears.TextChanged, txtInterestRate.TextChanged
        txtFutureValue.Text = ""
        txtInvestments.BackColor = Color.White
        txtInterestRate.BackColor = Color.White
        txtYears.BackColor = Color.White
        txtFutureValue.BackColor = Color.White


    End Sub

    Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
        Me.Close()

    End Sub

End Class

I have everything working right. I can change the textbox background color with all exceptions but the final exception in the Private Sub btnCalculate_Click. I understand the logic but I do not know how to code this in VB.Net.
 
First up, let me suggest that you just call ex.ToString, which will give all that information.

Secondly, there's no need for any exceptions there anyway. You should call Double.TryParse to convert the String to a Double and then convert that to a Decimal or an Integer. Double.TryParse will return a Boolean to indicate success or not, so no exceptions needed. You'll also know exactly which value failed conversion so highlighting a control is no issue.

Note also that Double.TryParse lets you specify a number style so you can force it to only accept integers if required.

Finally, .NET 20 and later add TryParse method to all numeric types as well as Date and Boolean. Just one of the many reasons to upgrade if possible. In case you don't know, VB 2008 Express is free.
 
Instead of all that unnecessary code, do as was suggested and use the TryParse method in the textbox's Leave event. If it cannot successfully convert (including a blank textbox) then it will return 0.

Dim number As Double
Double.TryParse(txtBox.Text, number) 'if false, it will return 0 to number
If number < min Or number > max Then 'assuming min is > 0
txtBox.Clear()
txtBox.Focus()
MessageBox.Show("Wrong entry. Try again.")
End If


In your button event:

If txtBox.txt = "" Then Exit Sub

This will not allow the code to execute unless the textbox is filled with the proper data.
 
Instead of all that unnecessary code, do as was suggested and use the TryParse method in the textbox's Leave event. If it cannot successfully convert (including a blank textbox) then it will return 0.

Dim number As Double
Double.TryParse(txtBox.Text, number) 'if false, it will return 0 to number
If number < min Or number > max Then 'assuming min is > 0
txtBox.Clear()
txtBox.Focus()
MessageBox.Show("Wrong entry. Try again.")
End If


In your button event:

If txtBox.txt = "" Then Exit Sub

This will not allow the code to execute unless the textbox is filled with the proper data.
That's the right idea but the Leave event is the wrong choice. You should use the Validating event for this, which is specifically intended to be used to prevent the user leaving a control before they've entered a valid value. You can even use the event to validate controls that the user has never visited, which can't be done with Leave.
VB.NET:
Private Sub TextBox1_Validating(ByVal sender As Object, _
                                ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
    Dim value As Double

    If Not Double.TryParse(Me.TextBox1.Text, _
                           Globalization.NumberStyles.Float, _
                           Nothing, _
                           value) Then
        'Prevent the control losing focus while it contains invalid data.
        e.Cancel = True

        'Highlight the data and notify the user.
        Me.TextBox1.HideSelection = False
        Me.TextBox1.SelectAll()
        MessageBox.Show("Please enter a valid decimal number.", _
                        "Invalid Value", _
                        MessageBoxButtons.OK, _
                        MessageBoxIcon.Error)
        Me.TextBox1.HideSelection = True
    End If
End Sub

Private Sub TextBox2_Validating(ByVal sender As Object, _
                                ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox2.Validating
    Dim value As Double

    If Not Double.TryParse(Me.TextBox2.Text, _
                           Globalization.NumberStyles.Integer, _
                           Nothing, _
                           value) Then
        'Prevent the control losing focus while it contains invalid data.
        e.Cancel = True

        'Highlight the data and notify the user.
        Me.TextBox2.HideSelection = False
        Me.TextBox2.SelectAll()
        MessageBox.Show("Please enter a valid integer.", _
                        "Invalid Value", _
                        MessageBoxButtons.OK, _
                        MessageBoxIcon.Error)
        Me.TextBox2.HideSelection = True
    End If
End Sub

Private Sub Button1_Click(ByVal sender As Object, _
                          ByVal e As System.EventArgs) Handles Button1.Click
    If Me.ValidateChildren() Then
        'All controls passed validation so we know they contain valid data.
        Dim dec As Decimal = Convert.ToDecimal(Me.TextBox1.Text)
        Dim int As Integer = Convert.ToInt32(Me.TextBox2.Text)

        'Use the data here.
    End If
End Sub
Note that the data in TextBox1 is validated as a Float, while the data in TextBox2 is validated as an Integer.

The call to ValidateChildren in the Button's Click event handler will raise the Validating event of every child control. This ensures that even controls that have never had focus will be validated. ValidateChildren will return False if any control fails validation, so we can use the data safely inside the If block because we are assured that the data is valid. No need for any exceptions or exception handling.
 
Back
Top