4

I'm running into a very peculiar issue. I noticed that occasionally while typing into my TextBox, I'll lose some keystrokes. I added a bunch of trace statements in events hooked by this TextBox, and I found that when I lost keystrokes, the KeyUp, KeyDown, and KeyPress events all correctly fired, but the TextChanged event never fired.

Does anybody have any idea why this would happen? I could write this off as a ".NET bug", but I'd rather figure out if there is a solution here.

In case there is a suggestion that I use the KeyUp/KeyDown events to determine if the text has changed, there is an issue there as well. KeyUp/KeyDown are called multiple times for each key press, so it would be very difficult to determine if someone was typing the same letter multiple times.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
dreadpirateryan
  • 545
  • 1
  • 7
  • 16
  • What keystrokes are you using to experience this? Textchanged is part of the property called Text for the textbox, and any input (alpha and numerical along with symbols such as $) fires off the TextChanged event, arrow keys, insert,overwrite do not fire but are caught by the KeyUp/KeyDown event. – t0mm13b Jan 06 '10 at 01:52
  • An obvious example would be pressing Backspace when the text box is empty. No TextChange event but all the keyboard events. – Hans Passant Jan 06 '10 at 02:18
  • I'm definitely using normal alphanumeric keystrokes when this is happening. – dreadpirateryan Jan 06 '10 at 20:09
  • I changed your title, since this has nothing to do with C# other than the fact it's the language you happen to be using to write .NET code. – John Saunders Jan 06 '10 at 21:14
  • Same happening with me particularly when I press backspace with one character in the TextBox (it goes blank from one character which is again a change in text value). And it also doesn't fire when I press Delete having all the text of TextBox selected. – IsmailS Jan 12 '11 at 07:48

3 Answers3

3

Hmmm....

This is going to be a shot, but, you did say you have the KeyUp, KeyDown and KeyPress event handlers right? Have you set the flag e.Handled to true in the event handlers, have a look here:

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            e.Handled = true;
        }

        private void textBox1_KeyUp(object sender, KeyEventArgs e)
        {
            e.Handled = true;
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = true;
        }

Have a look here in the MSDN about this Handled property. (If you have MSDN 2008 SP 1 installed locally, the link is ms-help://MS.MSDNQTR.v90.en/fxref_system.windows.forms/html/dfc80b44-1d79-6315-cbea-1388a048c018.htm)

To quote:

Handled is implemented differently by different controls within Windows Forms. 
For controls like TextBox which subclass native Win32 controls, it is 
interpreted to mean that the key message should not be passed to the underlying 
native control. 

If you set Handled to true on a TextBox, that control will not pass the key 
press events to the underlying Win32 text box control, but it will still 
display the characters that the user typed. 

Maybe it is not set i.e. e.Handled = false; thereby preventing the TextChanged Event from firing?

Can you check and confirm this?

Edit: After dreadprivateryan's response, I can suspect (due to lack of code posted), based on his response, e.Handled is true for when Enter key is pressed and false for everything else which in my mind, thinks that is the reason why no further keystrokes are being accepted as a result of this.

  • Are you trying to set focus to another control upon the Enter key being pressed? It could be that both KeyUp and KeyDown are conflicting...
  • Remove the keyboard hook and disable it...
  • My suggestion is to change the code completely in this manner as shown, take out either KeyDown or KeyUp Event Handler as they, simplistically put it, are the same, ok, technically, it is designated respectively for when a key is pressed down, and likewise when a key is released. Have a look at this link here. There was a similar question posted here on SO.

In the example below, I used the keyUp event handler to switch focus to the next available control upon enter key being pressed. In the KeyPress event handler, this simply filters the input and only allows numbers 0-9 respectively, anything else gets discarded. Included in that event handler, is the allowance for the backspace key to provide editing.

        private void textBox1_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter) SendKeys.Send("{TAB}");
        }
        private const string VALID_KEYS = "0123456789";
        private void textBox1_KeyPress(object sender, KeyPressEventArgs e) 
        {                  
            if (VALID_KEYS.IndexOf(char.ToUpper(e.KeyChar)) != -1 || e.KeyChar == (char)8) 
                 e.Handled = false;                                                               
            else                                                                                 
                 e.Handled = true;                                                                
}                                                                                        

Hope this helps, Best regards, Tom.

Community
  • 1
  • 1
t0mm13b
  • 34,087
  • 8
  • 78
  • 110
  • Thanks for the suggestion. I am only setting e.Handled=true in the case that the keystroke is an enter key, and otherwise I'm not setting handled at all. Unfortunately I don't think this is related to my issue -- I'm losing keystrokes whether or not I press Enter. – dreadpirateryan Jan 06 '10 at 21:29
1

I don't actually know, but I have a random guess: You running in a VM?

One hack you could use is make a timer that reads the text and compares to the previously entered value. Call the event handler code when it isn't equal to the previously checked value. When you need to use the final entered value, do one additional check, in case the timer hasn't fired yet.

Merlyn Morgan-Graham
  • 58,163
  • 16
  • 128
  • 183
0

Do you mean the keypress is actually lost and never shows up in the box? Or do you mean you don't get a TextChanged event for every keypress?

I believe the TextChanged event is driven by the operating system's EN_CHANGE notification which is sent via a WM_COMMAND message. I know that certain kinds of messages in Windows are "coalesced" to avoid redundant notifications. For example this can happen with WM_MOUSEMOVE messages and is why you don't receive a mouse move event for every pixel that the mouse moves across the screen.

I can't say for sure but I suspect that the TextChanged event behaves this way as well. I can say though that alternate input methods have this side effect too. When using a Tablet PC input panel, the textbox will not get a TextChanged notification for every character.

Josh
  • 68,005
  • 14
  • 144
  • 156
  • The key is actually lost and never shows up in the box -- and when that happens, I noticed that the TextChanged event doesn't fire as well. Thanks for the info on the Windows messages. Maybe I can manually fire that event during the KeyUp/KeyDown events? – dreadpirateryan Jan 06 '10 at 01:42
  • 1
    It seems like something is eating the message. Maybe there is a system-wide message hook installed somewhere that is acting up? Or dare I say, maybe some kind of keylogger? You should try running Spy++ if you have it installed and see if the message gets to the window. – Josh Jan 06 '10 at 01:50
  • There is indeed a keyboard hook in the program -- an important piece of info I should have included. The hook is created using the following code: SetWindowsHookEx(WH_KEYBOARD, KeyFunction, dllInstance, AppDomain.GetCurrentThreadId()); The KeyFunction method checks for certain keystrokes, calls other functions depending on what those keystrokes are, and then calls the CallNextHookEx function. My trace statements tell me that in the cases where I'm losing keystrokes, the hook does indeed see the key, and CallNextHookEx function is getting called properly. – dreadpirateryan Jan 06 '10 at 20:16
  • 1
    Can you confirm that without the hook the keystrokes are not lost? Perhaps you could post a snippet of the code around the hook proc. – Josh Jan 07 '10 at 00:17