Solved

Problems with Try...Catch

Posted on 2014-01-26
14
327 Views
Last Modified: 2014-01-28
I am new to VB.NET and to some of the new concepts.  I have a form on which I have two masked text boxes with the mask set to Time (__:__).  The program works fine if legal times are entered.  If I enter an illegal time (e.g. 89:78) into the txtStartTime box and tab out of the box the error is trapped in the LostFocus event, however in stepping through (break point set at the "Try" line), the execution goes to the Catch then the System.Windows...line then jumps to the txtEndTimeLostFocus event, and shows the text box for the End time event.  I'm sure this is something stupid on my part, but I just can't see it.
Any help would be appreciated!
Thanks
    Private Sub txtStartTime_GotFocus(sender As Object, e As EventArgs) Handles txtStartTime.GotFocus
        txtStartTime.SelectAll()                            ' Causes the field to highlight
    End Sub

    Private Sub txtStartTime_LostFocus(sender As Object, e As EventArgs) Handles txtStartTime.LostFocus
        Try
            dtSTime = txtStartTime.Text                     ' Set the Start time value
            txtTotalTime.Text = CalcTime(dtSTime, dtETime)  ' Calculate the elapse time between the start and end times
        Catch
            System.Windows.Forms.MessageBox.Show("Hours:0-23, Minutes:0-59", "Illegal Start Time", MessageBoxButtons.OK)
            With txtStartTime                               ' Set thee focus back to the Start Time
                If .Text.Trim <> "__:__" Then
                    .Focus()
                End If
            End With
        End Try
    End Sub

    Private Sub txtEndTime_GotFocus(sender As Object, e As EventArgs) Handles txtEndTime.GotFocus
        txtEndTime.SelectAll()
    End Sub

    Private Sub txtEndTime_LostFocus(sender As Object, e As EventArgs) Handles txtEndTime.LostFocus
        Try
            dtETime = txtEndTime.Text
            txtTotalTime.Text = CalcTime(dtSTime, dtETime)
        Catch
            System.Windows.Forms.MessageBox.Show("Hours:0-23, Minutes:0-59", "Illegal End Time", MessageBoxButtons.OK)
            With txtEndTime
                If .Text.Trim <> "__:__" Then
                    .Focus()
                End If
            End With
        End Try
    End Sub

Open in new window

vs2012-issue.txt
0
Comment
Question by:TopCatOnyx
  • 7
  • 6
14 Comments
 
LVL 5

Expert Comment

by:Kwoof
ID: 39810797
The easiest way...would be to have 4 boxes if it doesn't clutter up the UI.  (separate boxes for minutes and hours that can be validated easily by a number range)...then you could build the string for the time...or build the time directly by feeding the minute and hour parameters?

Otherwise...you need to parse  (look for the ":" to grab the numbers before and after it...and to make sure a ":" is present as well!) and validate the hours and minutes BEFORE assigning it to the variable to avoid creating an exception.
0
 
LVL 40
ID: 39810808
First of all, take the habit of checking online help for almost everything. Old habits from VB6 (that seem to show in your code) do not always carry well in .NET. For instance, if you look in help for the Focus method, you will see the following note: Focus is a low-level method intended primarily for custom control authors. Instead, application programmers should use the Select method or the ActiveControl property for child controls, or the Activate method for forms.

This is one of the most commonly seen error seen in VB.NET, even for programmer who never programmed in VB6, because they see it repeated everywhere.

Also, explore events a bit. There are a lot more events in .NET than there were in VB6, and some of these might be a lot more interesting to use. LostFocus is not used often by programmers who know the .NET events well.

There is a Validating event, that is triggered before the LostFocus, and that is better suited for validation as its name implied. It's e parameter has a Cancel property that you can set to True. That does not prevents that particular event, since it has already been triggered, but it prevents all the following ones.

It thus prevents the LostFocus, so you do not have to bring back the focus in the control, it stays there. And it won't go into the following control either, so it should correct your primary problem.

Simply move your code in the Validating event, change the .Focus for e.Cancel=False, and unless there is something I did not catch, this should solve your problem and perform validation in the way it was designed to be in .NET.
0
 

Author Comment

by:TopCatOnyx
ID: 39810835
Hi JamesBurger,
I moved the Try..Catch..End Try code to the Validating event and that fixes most of the problem.  I also added the e.Cancel statement (= False) in place of the With ... End With block.  Now when I click OK on the message box, focus jumps to the next tab stop (if I'm inputting the start time, focus jumps to the end time box rather than remaining with the start time block.
0
 
LVL 40
ID: 39810854
Have you tried putting a breakpoint on e.Cancel=False to see if it is hit?

The TabStop move should not happen when you use that.

If it does get hit, then go on step by step to see if something else is no triggering the move.
0
 

Author Comment

by:TopCatOnyx
ID: 39810938
Hi JamesBurger,
The first step after the breakpoint was to the End Try then End Sub.  After that it went to the txtEndTime_GotFocus event.  I then removed both GotFocus events and it went to the txtEndTime box.  The txtStartTime box was left with an illegal time.
Not sure what is happening.
0
 
LVL 40

Accepted Solution

by:
Jacques Bourgeois (James Burger) earned 500 total points
ID: 39811140
Ooops. Sorry, mistake on my side. In the first part of my solution, I tell you to set Cancel to True, but in the end, I said False by mistake. And rereading your message from earlier, I see that you took the last advice... the bad one.

You do want to Cancel, so you should set Cancel to True.

Sorry.
0
 

Author Comment

by:TopCatOnyx
ID: 39811996
Hi JamesBurger,
That took care of the problem - last issue - how would you enable leaving the textbox without entering any time - like trying to click Cancel on the form?  With the code we have now, if you try to click anywhere outside the StartTime text box without entering any time, you get the error message, and can't get out until a valid time has been entered.
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 40
ID: 39812201
In your error message, tell the user to enter a valid time or leave the TextBox empty. Take care of that second posibility in your evaluation.
0
 

Author Comment

by:TopCatOnyx
ID: 39812425
Hi JamesBurger,
here is what I have in my Validating routine:
        Try
            dtSTime = txtStartTime.Text                     ' Set the Start time value
            txtTotalTime.Text = CalcTime(dtSTime, dtETime)  
        Catch
            Result = System.Windows.Forms.MessageBox.Show("Please enter a valid Start time: Hours:0-23, Minutes:0-59", "Illegal Start Time", MessageBoxButtons.RetryCancel)
            If Result = Windows.Forms.DialogResult.Cancel Then
                Close()
                I have also tried: cbCancel_Click(txtStartTime, e)
            Else
                e.Cancel = True
            End If
        End Try
In both cases (Close() or clicking the Form Cancel button) the Close/Cancel is ignored.  I also tried setting e.Cancel = False in the "Then" clause - same thing.
Any thoughts?
0
 
LVL 40
ID: 39812466
And naturally, you went step by step to make sure that the lines were hit.

e.Cancel = True should work, you have seen it before.

Could you post the whole event procedure?

I will not be able to answer for a few hours, I have to go outside for a while, and we have heavy snow and winds actually in the Montréal area. I do not know when I will be back.
0
 

Author Comment

by:TopCatOnyx
ID: 39812530
Hi JamesBurger,
Yes, I stepped through the routine.  When it hits the Close() statement is just continues (doesn't seem to execute the close statement) to the EndTime text box which is the next tab index.

Don't get blown away with the snow flakes!  We have high wind, cold (for here in SW Texas), but no snow - thankfully since most don't know how to drive in the snow here (I came from northern MN).
    Private Sub txtStartTime_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles txtStartTime.Validating
        Try
            dtSTime = txtStartTime.Text                     ' Set the Start time value
            txtTotalTime.Text = CalcTime(dtSTime, dtETime)  ' Calculate the elapse time between the start and end times
        Catch
            Result = System.Windows.Forms.MessageBox.Show("Please enter a valid Start time: Hours:0-23, Minutes:0-59", "Illegal Start Time", MessageBoxButtons.RetryCancel)
            If Result = Windows.Forms.DialogResult.Cancel Then
                e.Cancel = False
                cbCancel_Click(txtStartTime, e)
' Also tried Close() in place of the cbCancel_Click call
            Else
                e.Cancel = True
            End If
        End Try
    End Sub

    Private Sub txtStartTime_GotFocus(sender As Object, e As EventArgs) Handles txtStartTime.GotFocus
        txtStartTime.SelectAll()                            ' Causes the field to highlight
    End Sub

    Private Sub cbCancel_Click(sender As Object, e As EventArgs) Handles cbCancel.Click
        Close()
    End Sub

Open in new window

vs2012-issue.txt
0
 
LVL 40
ID: 39813651
Hi, I'am back. Not blown away, but stranded with a 40 cars pile up a few kilometers in from of me, and another smaller one in my back. Stuck  in between 2 hours in a cheap coffee shop that did not have wifi. And the meteo was showing "Bright and Sunny". I don't know what OS runs on their computers.

Back to your stuff, it's over my head. Nothing seems to do what it should.

Here are the next things I would try if I was stuck in that strange situation:

- Make sure that you do not have a method called Close in the Form. This would override the normal Close coming from the base class, and in one of its stupid ways of doing things sometimes, the compiler treats that only as a Warning even if you set all the options rights to prevent that type of stupidity.

- Put something in the Close event of the Form to see if Close really is not executed.

- Same as for the Focus in an earlier message, there are too many bad examples running around coming from VB6 programmers that did not see that their old habits are bad habits nowadays. GotFocus and LostFocus are usually not the right events to use in .NET. Enter and Leave are the preferred ones. Moving your GotFocus and LostFocus events to Enter and Leave might make a difference. Maybe. Validating is still the best one to call when validating, but when the idea is to perform some operation or format something, Enter and Leave are usually a better choice. Look them up in the documentation to see in which order they are called and what the little différences are.

- Finally, a solution I do not like at all because although it might help correct the problem, but since you never identified it, it may come back to haunt you somewhere else. Have a form level Boolean variable that you set to True when you catch the error in txtStartTime. When you Enter txtEndTime, check for that flag. If True, set it to False and call a Selelct on txtStartTime to bring back the focus to it. Finally, add a BIG ToDo comment to come back later to try to understand what is happening. Your mind might be feeling things differently and find it in 2 minutes. One of my friends advocates a double Scotch to help doing this, but I have tried, and although it's quite pleasurable if the Scotch is good, it does not seem bo work.

Still listening to your follow ups, but since I give 2 days of training starting tomorrow, my answers could be long in coming. Maybe somebody will jump in with fresh ideas before I can be back.
0
 

Author Closing Comment

by:TopCatOnyx
ID: 39815234
Hi JamesBurger,
I came up with a different way to handle the input of the times - using the DateTimePicker.  Set it up to be a 24 hour clock (Custom Format, HHmm), ShowUpDown = True.  You can't enter an illegal time.  The only validation needed is to check to make sure that the start time is before the end time.  The only disadvantage is that this method requires one additional key stroke to get from the hours to the minutes, where with the masked text box, it is automatic.

Anyway, you were tremendously helpful in making me try to start thinking differently about VB.NET and how to approach programming using the language.  I must admit that it isn't easy after more than 20 years of programming in VB (4-6)!

Thanks again
0
 
LVL 40
ID: 39816582
Moving from VB6 to VB.NET is, indeed, not easy. I lived it in 2002 after having spent a decade in VB (2-6). And even with the C++ background I had before that (so a more object oriented language was not something new to me), I still remember the pain of moving from VB6 to that new .NET thing that was presented in such a way that nobody really understood where Microsoft was going to.

In the training I give to programmers coming from different backgrounds, I find that programmers who come another language than VB6 very often have less problems. They have a new syntax to learn, but after all, an If or a For is a concept that exists in all languages.

Learning to work outside of the language, which is what you do in the framework where the language does not do much, the framework is the one really working, is another thing. Programmers who come from a language other than VB often have an edge on that topic.

They are not slowed down by the baggage that they need to dump from their expertise in VB6 in order to succeed in .NET. Many come from a background where Try...Catch exists, while VB6 programmers often have a hard time moving out of On Error GoTo. Many come from languages where you cannot work without creating a class of your own, so moving to a completely object oriented language is nothing new. Many come with a web background, so working with databases in a disconnected context is also old stuff for them.

Except for the syntax, VB.NET has more to do with Java than it does with VB6.

So, yes, it's hard. But it's worth every hour of hard work that you put into it. Once configured properly it is a very effective professional tool. Once you master it, you do what you want with it, more efficiently, with more performance, all of this while writing a lot less lines that it would have taken in VB6.

It just requires some patience at the beginning.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This video discusses moving either the default database or any database to a new volume.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now