On Mon, 25 Oct 2004 21:06:46 -0400, Adam J. Schaff wrote:
> Jay,
>
> The debug statements were a great idea. However, I appear to have confused
> things with my sample application, which was only designed to illustrate
> that Form1 was receiving a KeyUp from a key press that occurred on Form2.
> Perhaps you're used to this, but it was an unpleasant surprise for me.
>
> So let me start over with a sample that more closely mirrors my real
> application. My app starts with Form1 which has a textbox on it. I want to
> display Form2 if the user presses Enter while in the textbox. I'm using the
> KeyUp event of the textbox for that. Form2 has an OK button, and has its
> AcceptButton set to that OK button. The scenario runs like this:
>
> 1. App starts, Form1 is shown, the textbox has focus
> 2. The user presses Enter. Form2 is then shown modally.
> 3. The user does his thing on Form2 and then presses Enter, expecting to be
> returned to Form1.
>
> Here is the sequence of events for step 3:
>
> a. No KeyDown or KeyPress events fire. Presumably, by setting the
> AcceptButton property of Form2, it is now intercepting and "handling" those
> events.
> b. The Click event of the OK button on Form2 fires, which closes Form2.
> c. The KeyUp event of TextBox1 on Form1 fires, which, as described above,
> launches Form2.
>
> The user is confused. He pressed enter, he saw Form2 unload, but then it
> reloaded immediately. If he presses Enter again, then it repeats (Form2
> closes and reopens).
>
> I guess I can work around this by using the KeyDown or KeyPress events. I
> don't like them as much as KeyUp, because KeyUp is guaranteed to only fire
> once per key press, whereas the others can fire over and over (if the user
> holds the button down), but they suddenly seem a lot safer in light of this
> issue.
>
> What I was hoping was that there might be some way that I could prevent the
> KeyUp event from happening. Not handle it, mind you, because by then I'm in
> Form1 and I can't tell a "good" KeyUp from a bad one. But if I could somehow
> intercept and clear it, say from the Closing event of my Form2, that would
> be cool.
>
> You see, the bigger issue here is how can I defend one window from events
> caused by a user who is in another window? Unwanted KeyUp and/or MouseUp
> events can be a rude surprise. It would be nice if there was some way for a
> form that was closing to say "throw away any outstanding KeyUp or MouseUp
> events that have not occurred yet".
>
> Thanks again for your help,
> -AJ
>
> "Jay B. Harlow [MVP - Outlook]" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> Adam,
>> To see why it happens add the following code to Form1:
>>
>> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
>> System.EventArgs) Handles Button1.Click
>> Debug.WriteLine("Click", "Button1")
>>> Dim f As New Form2
>>> f.ShowDialog()
>> End Sub
>>
>> Private Sub Button1_KeyUp(ByVal sender As Object, ByVal e As
>> System.Windows.Forms.KeyEventArgs) Handles Button1.KeyUp
>> Debug.WriteLine("KeyUp", "Button1")
>> End Sub
>>
>> Private Sub Button1_KeyDown(ByVal sender As Object, ByVal e As
>> System.Windows.Forms.KeyEventArgs) Handles Button1.KeyDown
>> Debug.WriteLine("KeyDown", "Button1")
>> End Sub
>>
>> Private Sub Button1_KeyPress(ByVal sender As Object, ByVal e As
>> System.Windows.Forms.KeyPressEventArgs) Handles Button1.KeyPress
>> Debug.WriteLine("KeyPress", "Button1")
>> End Sub
>>
>> Private Sub Button1_MouseDown(ByVal sender As Object, ByVal e As
>> System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown
>> Debug.WriteLine("MouseDown", "Button1")
>> End Sub
>>
>> Private Sub Button1_MouseUp(ByVal sender As Object, ByVal e As
>> System.Windows.Forms.MouseEventArgs) Handles Button1.MouseUp
>> Debug.WriteLine("MouseUp", "Button1")
>> End Sub
>>
>>
>> Run your form. Watch the debug messages, especially when you press Enter
>> (or Space) when Form1.Button1 has the focus & doesn't have the focus. Also
>> watch when there are other controls earlier & later in the tab order on
>> Form1.
>>
>> Assuming there are no other controls on Form1:
>>
>> When Form1.Button1 does not have the focus, Button1 gains the focus & does
>> the Click event, Form1.Button1 now has the focus, so Form1.Button1.KeyUp
>> event is raised.
>>
>> When Form1.Button1 does have the focus, Button1 raises its KeyDown &
>> KeyPress event, then the Click event, followed by the KeyUp event.
>>
>> MouseDown, Click, and MouseUp events happen in a similar order.
>>
>> IMHO Preventing it seems rather easy, Don't handle the Form1.Button1.KeyUp
>> event, or if you do need to handle it, make sure you know when the event
>> is occurring as part of the Click event or another event...
>>
>> Hope this helps
>> Jay
>>
>>
>>
>> "Adam J. Schaff" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed)...
>>> Jay,
>>> To reproduce, create a new vb.net winforms app with two forms. Place a
>>> button on each form.
>>> Add this code to form1:
>>> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
>>> System.EventArgs) Handles Button1.Click
>>> Dim f As New Form2
>>> f.ShowDialog()
>>> End Sub
>>>
>>> Private Sub Button1_KeyUp(ByVal sender As Object, ByVal e As
>>> System.Windows.Forms.KeyEventArgs) Handles Button1.KeyUp
>>> Stop
>>> End Sub
>>>
>>>
>>> Add this code to form2:
>>>
>>> Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As
>>> System.EventArgs) Handles MyBase.Load
>>> Me.AcceptButton = Button1
>>> End Sub
>>>
>>> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
>>> System.EventArgs) Handles Button1.Click
>>> Me.Close()
>>> End Sub
>>>
>>> Run the app, click the button on form1. Form2 opens, press Enter. Note
>>> that
>>> the breakpoint in form1 gets hit! I don't understand why, since enter was
>>> pressed while form2 was open. More importantly, I don't understand how to
>>> prevent it.
>>>
>>> p.s. framework v1.1, windows xp-sp2
>>>
>>>
>> <<snip>>
>>
I created a very small project. It has two forms. On Form1, I placed a
single textbox. It's keyup handler is shown below:
Private Sub TextBox1_KeyUp(...) Handles TextBox1.KeyUp
If e.KeyCode = Keys.Enter Then
Dim f As New Form2
Debug.WriteLine("Form1: TextBox1: KeyUp")
f.ShowDialog()
f.Dispose
End If
End Sub
On Form2 I placed a single button. I then set the AcceptButton propert of
Form2 to be the button. I added the following code to the Button's click
event:
Private Sub Button1_Click(...) Handles Button1.Click
Debug.WriteLine("Form2: Button1: Click")
Me.Close()
End Sub
When I fire up the program, Form1 appears with the textbox having focus
(since it is the only control on the form). I press enter and Form2
appears. I press enter again which causes the button on form2 to be
clicked which closes form2. Form2 immediately reappears!!
The following text appears in the output windows:
Form1: TextBox1: KeyUp
Form2: Button1: Click
Form1: TextBox1: KeyUp
Where is that extra KeyUp event coming from? When I pressed Enter, *FORM2*
had focus, form1 should not have gotten a keypress from form2!!
What appears to be happening is that the AcceptButton is being triggered
when the key goes down, which closes the form, but then the key up occurs
after form2 has been closed so the keyup goes to the only form which has
focus: Form1, which, of course, opens form2 again!
While, perhaps, its behavior is undesired, it is logical. The only
workaround I could think of was by adding a boolean flag that is set right
after form2 is closed and checking that flag on entering the keyup event.
If set, don't show form2 again:
'Global boolean
Dim bForm2JustClosed As Boolean
Private Sub TextBox1_KeyUp(...) Handles TextBox1.KeyUp
If e.KeyCode = Keys.Enter Then
'If Form2 just closed, then ignore this KeyUp for the Enter key
If bForm2JustClosed Then
bForm2JustClosed = False
Exit Sub
End If
Debug.WriteLine("Form1: TextBox1: KeyUp")
Dim f As New Form2
f.ShowDialog()
f.Dispose()
'Form2 just closed so set the flag to indicate this
bForm2JustClosed = True
End If
End Sub
This code seems to work for my simple test app, but whether or not it can
work for you, I don't know. Perhaps another option is in the keyUp event
for the textbox, set focus to some hidden control so that IT receives the
keyup event when form2 is closed then in it's keyup event, restore focus
back to the textbox.
Anyway, just wanted to let you know you are not losing your mind.
--
Chris
dunawayc[AT]sbcglobal_lunchmeat_[DOT]net
To send me an E-mail, remove the "[", "]", underscores ,lunchmeat, and
replace certain words in my E-Mail address.