C#多行文本框(Textbox)的TextChanged事件为什么会触发两次?

5

我在WinForms的多行文本框中遇到了一个非常奇怪的TextChanged事件问题。在某些情况下,该事件会触发两次。

以下完整代码展示了这个问题:

public partial class TextChangedTest : Form
{
    public TextChangedTest()
    {
        InitializeComponent();
    }

    private void TextChangedTest_Load(object sender, EventArgs e)
    {
        TextBox tb = new TextBox();
        //Remove the following line and the code behaves as expected
        tb.Multiline = true;
        this.Controls.Add(tb);
        tb.TextChanged += new EventHandler(tb_TextChanged);
    }
    private void tb_TextChanged(object sender,EventArgs e)
    {
        //Need to validate and use the new text here.
        //For testing, just use a MessageBox
        MessageBox.Show("Handler fired");
    }
}

如果您现在在文本框中输入字符,事件会触发。这是正确的行为。

如果您删除字符,事件会被触发一次。这是正确的行为。

如果您使用退格键删除字符,事件会被触发一次。这是正确的行为。

如果您选择字符并按Delete键删除该字符,事件会被触发一次。这是正确的行为。

然而

如果您选中一个字符并输入另一个字符,事件会被触发两次:第一次在文本框清空后触发(当第一个事件触发时,请查看文本框),第二次在添加字符时触发。这种行为是无意义的,但可以理解。

只有在设置了多行属性(我正在使用它来调整文本框大小)才会出现这种情况。我花了5个小时才弄清楚!

我的问题是,我必须在TextChanged事件中验证每个字符,但我得到了无效的结果。

有人有什么想法吗?

我可能可以使用Keypress事件,但我需要进行大量的重新编码才能做到这一点。


只是提供信息,我能够在.NET FW 4.5 VS2012中复制。 - deepee1
@deepee1 谢谢。不只是我又变傻了... - Blind Fury
1
当您选择一些文本然后按键以覆盖时,文本框实际上正在执行两个操作。它删除文本(第一个文本更改事件),然后插入新文本(第二个文本更改事件)。如果您将消息框更改为在每次更改时显示文本框的文本,则可以看到这一点。不确定为什么多行文本框会这样做。您可以查看源代码http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/TextBox.cs,577a143ad3bbfb97, - MisterXero
@MisterXero 是的。我自己解决了这个问题(它在问题中)。你可以看到当第一个 MessageBox 显示时,TextBox 是空白的。但对我来说,它只对多行文本框有效,这一点毫无意义。 - Blind Fury
1
我不知道。根据这篇已经十年历史的帖子,这并不是一个新问题。 - CodeCaster
显示剩余2条评论
1个回答

1

对于我的特定情况,解决方法更加奇怪。

我需要 Textbox 具有特定的大小,但是除非它是多行的,否则高度无法更改。

然而,在我的小世界里,以下内容对我有效:

    tb.Multiline = true;
    tb.Size = new Size(x,y);
    tb.Multiline = false;
    this.Controls.Add(tb);
    tb.TextChanged += new EventHandler(tb_TextChanged);

http://en.code-bude.net/tag/c-textbox-height-resize/找到解决方案。

但并没有解决根本问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接