Solved

How to handle wrong--or nonexistent--keypress event

Posted on 2008-10-18
5
483 Views
Last Modified: 2012-05-05
I have a vb 2005 app that runs in the compact framework environment.  A typical form might have these text boxes:

Location A
I------------I
I               I
I------------I

Location B
I------------I
I               I
I------------I

What the user is supposed to do is enter data into Location A, the press Enter, then enter data into Location B and press Enter, etc.  Here is an example of the code I use to handle this:

Private Sub txtLocA_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtLocA.KeyPress

        If e.KeyChar = ChrW(13) Then
            e.Handled = True

        (Various routines here to handle data)

EndSub

But here is the problem: Sometimes they don't press Enter, and instead press the down-arrow key, or sometimes they don't press a key at all, instead touching the LocationB text box (since it is a touch screen portable device).  As result, none of the "various routines" get processed to handle the data.

So, I'm wondering if the best thing to do would be to implement a "LostFocus" event.  If not, I need some clear guidance on what WOULD be the best solution.

But if LostFocus is the way to go, than I need help with the syntax in the first line (Private Sub...)    I've tried things like replacing "Handles txtLocA.KeyPress" with 'Handles txtLocA.LostFocus", but I get syntax errors that I don't know how to resolve.

My assumption is that LostFocus "knows" what text box I'm in at any moment, and will run my Sub if I leave that text box for any reason.  Is it that simple?  Does it work reliably?

Finally, since most users are accustomed to pressing the Enter key, I still need to be able to handle that situation.  I assume that if a user is in a text box and presses Enter, that in itself will not cause the cursor to go to another text box--like the down arrow does, for example.  (I have no way of testing this at the moment, but another reason I think this is true is because my code has always included steps to tell the program where to focus next--such as location B).  So...assuming I still need to provide for the Enter key with this type of syntax now in use:

Private Sub txtLocA_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtLocA.KeyPress

        If e.KeyChar = ChrW(13) Then
            e.Handled = True

I then wonder if there is a way to handle the Enter key situation AND the LostFocus situation, without having to have two completely separate "Sub"s.  And the reason I'm concerned is because I have a LOT of code in each of these location Subs, and I would hate to have to repeat all the code each time--especially since I'm in a compact environment with limited resources.

I guess maybe there is a way I could call a routine that runs all the code from either the "Enter" Sub or the "LostFocus" Sub.  But what would be really nice is if there is a provision in vb 2005 that allows me to somehow structure the code in way that I could have one single sub that can both "Handles txtLocA.KeyPress" and "Handles txtLocA.LostFocus".  Is this even possible?  TIA
0
Comment
Question by:sasllc
  • 3
  • 2
5 Comments
 
LVL 12

Expert Comment

by:omegaomega
ID: 22749884
Hello, sasllc,

I think that you will find the TextBox's Validated event is the best place to put your code.  Depending upon your specific requirements you may also want to put some of your code in the Validating event.  Both these events are typically* called when the user changes the input focus to another control no matter how he does this.  You will need to retain just the code in the KeyPress event that changes to the next control when the user hits <Enter>.

If you are unhappy with what the user has entered in the TextBox, you can prevent them from leaving by setting e.Cancel to True in the Validating event.  If the Validating event is processed without being cancelled then the Validated event handler is called.

* Controls have a CausesValidation property that is normally True by default.  You can set this property to False for selected controls.  In this case the validation events will not be raised if focus is moved to that control.  One typical case where you might do this is if you have a [Cancel] button on your form.  If the user is cancelling her updates, then presumably you don't need to (and actually shouldn't) validate the entry that she has just made.

Cheers,
Randy
0
 
LVL 3

Author Comment

by:sasllc
ID: 22754225
Hmmm...unfortunately I don't understand much of what you're saying, probably due to my "beginner status" on this subject.  If possible, I need answers and guidance on the specific questions above, such as:

I need help implementing the LostFocus syntax in the first line (Private Sub...)    I've tried things like replacing "Handles txtLocA.KeyPress" with "Handles txtLocA.LostFocus", but I get syntax errors that I don't know how to resolve.
   --- and ---
My assumption is that LostFocus "knows" what text box I'm in at any moment, and will run my Sub if I was in that textbox and then leave that text box for any reason.  Is it that simple?  Does it work reliably?
   --- and ---
But what would be really nice is if there is a provision in vb 2005 that allows me to somehow structure the code in way that I could have one single sub that can both "Handles txtLocA.KeyPress" and "Handles txtLocA.LostFocus".

Sorry to be dense...but if you can help me with these specifics I think I'll be well on my way....thanks


0
 
LVL 12

Expert Comment

by:omegaomega
ID: 22755072
Hello, sasllc,

The attached code snippet demonstrates the approach that I'm recommending.  With regard to your specific questions:

Re: "I need help implementing the LostFocus syntax..."
I strongly suggest that you NOT use LostFocus for this purpose.  The documentation about the LostFocus event contains the statement: "...Typically, the GotFocus and LostFocus events are only used when updating UICues or when writing custom controls. Instead the Enter and Leave events should be used for all controls except the Form class, which uses the Activated and Deactivate events...

Re: "Does it (i.e. LostFocus) work reliably?"
Yes, but you will find that LostFocus is also called at times that you may not wish to process the user's entry.  For example, if part way through completing an entry, your user changes from your application to another application, LostFocus will be called causing the partial entry to be processed.

Re: "But what would be really nice is if there is a provision..."
There is no such provision. But there is no need to duplicate your code.  Just write your code in a separate procedure and call that procedure from each of the event handlers.

Hope that helps clear things up a bit.

Cheers,
Randy

Public Class Form1

    Private Sub txtLocA_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtLocA.KeyPress

        If e.KeyChar = ChrW(13) Then

            Me.GetNextControl(txtLocA, forward:=True).Select()

            e.Handled = True

        End If

    End Sub

    Private Sub txtLocA_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtLocA.Validated

        ' Replace the following line with "(Various routines here to handle data)"

        MsgBox("Your entry """ & txtLocA.Text & """ has been accepted.")

    End Sub

    Private Sub txtLocA_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles txtLocA.Validating

        ' This is just a silly example.  Place here whatever code 

        ' you need to ensure that the user's entry makes sense.

        If (Not txtLocA.Text.ToLower.Contains("baloney")) Then

            MsgBox("Your entry must contain the word ""baloney"".")

            e.Cancel = True

        End If

    End Sub

End Class

Open in new window

0
 
LVL 3

Author Comment

by:sasllc
ID: 22756719
Stepping through your helpful response...

"Instead the Enter and Leave events should be used for all controls except the Form class, which uses the Activated and Deactivate events..."

So the "Leave" event looks promising, but when I try to implement it, I get a syntax error: "Event 'Leave' cannot be found."  And, I added "Public Event Leave as EventHandler" near the top of my form code, as shown on msdn, but I still get the error.  Could this be because I'm developing for a mobile device with fewer options available to me?  Is there is a solution or alternative?

And, you said: "Just write your code in a separate procedure and call that procedure from each of the event handlers."  Again, this makes sense to me--by just writing a simple sub that would contain the editing code I've already implemented.

But are the ".validated" or ".validating" examples designed to do this editing automatically somehow?  Is ".validating" an event that continues to happen while the user is "in" this textbox?  And is ".validated" an event that happens one time, once they LEAVE this textbox?  

If not, I need to better understand WHEN and/or WHY these events happen....thanks

0
 
LVL 12

Accepted Solution

by:
omegaomega earned 500 total points
ID: 22758884
Hello, sasllc,

Please note that I am not recommending you use the Leave event.  I'm just passing along MS's advice that Leave is generraly more appropriate than LostFocus.  I've never worked with the mobile devices, but the documentation does not indicate that Leave is supported by the "Compact Framework" (which I guess is what you are using).  Also according to the documentation, Validating and Validated ARE supported by the Compact Framework.

I don't know what you mean by "designed to do this editing automatically somehow?"  There is no magic here.  (You might find the MaskedTextBox control to be helpful for some "automatic editing" requirements.)   In the case of the TextBox control, most editing is left up to you.  (The TextBox control does provide for automatic CharacterCasing.)

The Validating event occurs when the user "attempts" to leave the TextBox.  If you handle the Validating event, your code has the option of preventing the user from leaving the TextBox if the contents are inappropriate.  And yes, the Validated event occurs one time when they leave the TextBox.  (If the Validating event prevents the user from leaving the TextBox, then the Validated event will not fire.)

Re: "I need to better understand WHEN and/or WHY these events happen."
The documentation for the Validated events states:
<begin quote>
When you change the focus by using the keyboard (TAB, SHIFT+TAB, and so on), by calling the Select or SelectNextControl methods, or by setting the ContainerControl.ActiveControl property to the current form, focus events occur in the following order:

Enter
GotFocus
Leave
Validating
Validated
LostFocus

When you change the focus by using the mouse or by calling the Focus method, focus events occur in the following order:

Enter
GotFocus
LostFocus
Leave
Validating
Validated

If the CausesValidation property is set to false, the Validating and Validated events are suppressed.
If the Cancel property of the CancelEventArgs is set to true in the Validating event delegate, all events that would usually occur after the Validating event are suppressed.
<end quote>

Cheers,
Randy
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

743 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

13 Experts available now in Live!

Get 1:1 Help Now