简体   繁体   中英

.NET: TextChanged event for TextBox not always firing, even though KeyUp and KeyDown are firing

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.

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 ie 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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM