【问题标题】:Is there a Winforms textbox event that can fire any time a textbox is ACCESSED and not necessarily CHANGED?是否有一个 Winforms 文本框事件可以在文本框被访问且不一定被更改时触发?
【发布时间】:2020-07-17 13:44:24
【问题描述】:

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

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

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

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

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

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

我没有看到该控件上的另一个事件处理程序似乎可以执行我正在寻找的操作,但我想我会问人群。

谢谢!

【问题讨论】:

  • 检测用户何时进入或离开该字段。阅读:docs.microsoft.com/en-us/dotnet/api/…
  • 从您的代码中,永远不要直接设置.Text。相反,创建一个接收要设置的字符串的方法。在该方法中,您可以将“清除标志”设置为 false,然后设置 .Text 属性。清除标志后,您唯一直接触摸.Text 的地方就是该方法内部。
  • 那么,TextBox 是否绑定到数据源?当数据更新/更改或 CurrencyManager 设置 Current 对象时,通过 DataBindings 属性设置的 Binding 对象引发 Format(然后是 Parse)事件。
  • 您在谈论您的代码和解决方法,但您忘记展示这些。见minimal reproducible example
  • 在高层次上,这听起来很直接,但没有代码......我们无法猜测它们是如何组合在一起的。

标签: c# winforms textbox


【解决方案1】:

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

一种特殊的文本框
听起来像派生类:

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 会再次检查是否相等。如果你不想这样,看看source code of TextBox

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    相关资源
    最近更新 更多