为什么这不会导致无限循环的事件?

Pur*_*ari 35 .net c# events winforms textchanged

我有一个简单的应用程序,可以反转在另一个文本框中键入的任何文本.问题是,您可以修改任一文本框,更改将(字面上)反映在另一个文本框中.

我写了这段代码,相信它会引起问题.

private void realText_TextChanged(object sender, EventArgs e)
{
    mirrorText.Text = mirror(realText.Text);
}

private void mirrorText_TextChanged(object sender, EventArgs e)
{
    realText.Text = mirror(mirrorText.Text);
}

private string mirror(string text)
{
    return new string(text.Reverse().ToArray()).Replace("\n\r", "\r\n");
}
Run Code Online (Sandbox Code Playgroud)

然后我尝试了它,相信它会导致无限循环(realText变化mirrorText,另一个事件发生,mirrorText变化realText等).但是,除了预期的行为之外什么也没发生

我当然对此感到高兴,我可以把它放在这里.或者我可以吗?

我很确定TextChanged每当Text发生变化时都会被触发.这是事件中某些错误保护的预期行为,还是我很幸运?这个代码在另一台计算机,其他构建设置等上是否会出错?它可以很容易地修复:

private void realText_TextChanged(object sender, EventArgs e)
{
    if (realText.Focused)
    {
        mirrorText.Text = Mirror(realText.Text);
    }
}
Run Code Online (Sandbox Code Playgroud)

我可能会这样做是为了安全,但需要检查一下吗?(我甚至不会问是否推荐它.)

小智 30

根据评论,并且已经回答,TextChanged当您将Text属性设置为已有的值时,不会引发事件.

目前尚不清楚这是否是您可以放心使用的.这是一个合理的优化,如果.NET Framework的未来版本删除它,我会非常惊讶,但我不能说旧版本,也不能代表第三方实现(Mono).

为了绝对安全,我不会使用Focused您在问题中提出的检查.我会做完全相同的什么Text现在二传手一样.

private void realText_TextChanged(object sender, EventArgs e)
{
    var newMirrorText = Mirror(realText.Text);
    if (mirrorText.Text != newMirrorText)
        mirrorText.Text = newMirrorText;
}
Run Code Online (Sandbox Code Playgroud)

这具有防止无限递归的相同优点,但与您在表单中放置的其他代码相比可以更好地播放,这些代码会因某些其他事件而更改文本.


Wil*_*mpt 21

它不会导致循环的原因是它检查Text属性是否实际更改,即新值是否等于旧值.在你的情况下,mirror函数恰好反转自身,这导致两次传递后的相同文本.