.NET:TextBox的TextChanged事件并不总是触发,即使KeyUp和KeyDown正在触发

时间:2010-01-06 01:08:31

标签: c# .net winforms textbox

我遇到了一个非常特殊的问题。我注意到偶尔输入我的TextBox时,我会丢失一些按键。我在这个TextBox挂钩的事件中添加了一堆跟踪语句,我发现当我丢失击键时,KeyUp,KeyDown和KeyPress事件都被正确触发,但TextChanged事件从未被触发。

有人知道为什么会这样吗?我可以把它写成“.NET bug”,但我想知道这里是否有解决方案。

如果有人建议我使用KeyUp / KeyDown事件来确定文本是否已更改,那么也存在问题。每次按键都会多次调用KeyUp / KeyDown,因此很难确定是否有人多次输入相同的字母。

3 个答案:

答案 0 :(得分:3)

嗯....

这将是一个镜头,但是,你确实说过你有KeyUp,KeyDown和KeyPress事件处理程序吗?你有没有在事件处理程序中将标志e.Handled设置为true,请看这里:

        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;
        }

MSDN中查看此Handled属性。 (如果您在本地安装了MSDN 2008 SP 1,则链接为ms-help://MS.MSDNQTR.v90.en/fxref_system.windows.forms/html/dfc80b44-1d79-6315-cbea-1388a048c018.htm

引用:

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. 

也许没有设置ie e.Handled = false;从而阻止TextChanged事件被触发?

您能检查并确认吗?

编辑:在dreadprivateryan的回复之后,我可以怀疑(由于缺少发布的代码),根据他的回复,e.Handled在按下Enter键时为真,对于其他所有其他的则为false在我看来,认为这就是为什么没有进一步的击键被接受的原因。

  • 您是否尝试在按下Enter键时将焦点设置为另一个控件?可能是KeyUp和KeyDown都是冲突的......
  • 取下键盘挂钩并将其禁用...
  • 我的建议是以这种方式完全改变代码,如图所示,取出KeyDown或KeyUp事件处理程序,简单地说,它们是相同的,好的,技术上,它分别指定为按下一个键时当钥匙被释放时,同样如此。请查看此链接here。 SO上发布了一个类似的问题here

在下面的示例中,我使用keyUp事件处理程序在按下回车键时将焦点切换到下一个可用控件。在KeyPress事件处理程序中,这只是过滤输入,只允许数字0-9,其他任何东西都被丢弃。包含在该事件处理程序中的是允许退格键提供编辑。

        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;                                                                
}                                                                                        

希望这有帮助, 最好的祝福, 汤姆。

答案 1 :(得分:1)

我实际上并不知道,但我随机猜测:你在VM中运行?

您可以使用的一个黑客是制作一个读取文本的计时器,并与之前输入的值进行比较。当事件处理程序代码不等于先前检查的值时,调用它。当您需要使用最终输入的值时,请执行一次额外的检查,以防计时器尚未触发。

答案 2 :(得分:0)

你的意思是按键实际上已经丢失并且永远不会出现在包装盒中吗?或者你的意思是你没有得到每个按键的TextChanged事件?

我相信TextChanged事件是由操作系统的EN_CHANGE通知驱动的,该通知是通过WM_COMMAND消息发送的。我知道Windows中的某些类型的消息被“合并”以避免冗余通知。例如,WM_MOUSEMOVE消息可能会发生这种情况,这也是鼠标在屏幕上移动的每个像素都没有收到鼠标移动事件的原因。

我不能肯定地说,但我怀疑TextChanged事件也是这样的。我可以说,替代输入方法也有这种副作用。使用Tablet PC输入面板时,文本框不会为每个字符获取TextChanged通知。