首页 > 解决方案 > 是否有一个 Winforms 文本框事件可以在文本框被访问且不一定被更改时触发?

问题描述

我有一个 Winforms 应用程序,其中一个特定的文本框字段(“电话号码”)完全以编程方式更新,这是用户在另一个表单上搜索的结果,或者作为对整个主表单(已保存)数据的数据库的查询。

我们希望文本框在数据适合某些情况时显示为红色背景(空白是其中之一,但还有另一个字符串可以显示,我们需要将其视为“空白”)。所以我在 TextChanged 事件处理程序上安装了这个。

但是,有时用户会按下“清除”按钮来清除此表单上的人员数据/字段,包括此电话号码文本框。在这种情况下,我们不希望空白显示为红色。所以我调整了 TextChanged 事件处理程序来解决这个问题。好的,到目前为止,一切都很好。

然而,如果他们已经完成了 Clear 并且现在发生了另一次搜索,将其结果转储回字段中,如果更新的数据是空字符串或 null ......那么...... TextChanged 事件不会触发,因为 VALUE 不是变化。它已经是 Null/Empty。然而在这种情况下,我们希望触发 TextChanged 事件处理程序中的内容。

我不能使用验证事件处理程序,因为它只有在用户提供输入时才起作用(我认为?)

到目前为止,我的解决方法是在我们基本上在搜索结束时更新该字段之后强制事件处理程序触发(可能用 Null/Empty 更新 Null/Empty)。这有效。但似乎应该有更好的方法。??

我没有看到该控件上的另一个事件处理程序似乎可以满足我的要求,但我想我会问人群。

谢谢!

标签: c#winformstextbox

解决方案


显然,您需要一种特殊类型的 TextBox,它会在设置属性 Text 时触发事件,即使这不会导致更改。

一种特殊的 TextBox
听起来像派生类:

class MyTextBox : TextBox
{
    public override string Text 
    {
        get => base.Text;
        set
        {
            // if no change, only call OnTextChanged, otherwise call base.Text
            if (this.Text.Equals(value))
            {
                 base.OnTextChanged(EventArgs.Empty);
            }
            else
            {
                 base.Text = value;
            }
        }
    }
}

如果需要,请使用 stringComparer,例如 OrdinalIgnoreCase。

public IEqualityComparer<string> TextComparer {get; set;} = StringComparer.OrdinalIgnoreCase;

public override string Text 
{
    get => base.Text;
    set
    {
        if (this.TextComparer.Equals(this.Text, value))
        ...

方法的缺点是base.Text = value会再次检查是否相等。如果你不想这样,看TextBox的源代码

public string Text
{
    get { return (string) GetValue(TextProperty); }
    set { SetValue(TextProperty, value); }
}

如果单击 SetValue,您将跳入窗口深处。我不确定您是否想到达那里,因为您不会每秒多次更新 Text 属性。


推荐阅读