【问题标题】:Stop TextChanged event from firing Leave event停止 TextChanged 事件触发 Leave 事件
【发布时间】:2011-09-23 02:41:26
【问题描述】:

我正在为一所公立学校开发一个简单的 WinForms 应用程序,用户可以通过输入他们的网络 ID(受保护的信息)或系统 ID(受保护的信息)。当程序检测到系统 ID(工作正常)时,我想切换到密码字符;但是,当我这样做时,我的应用程序也会触发文本框的 Leave 事件,该事件会告诉用户解决登录数据的问题......甚至在出现问题之前。

这是我的代码:

void login_TextChanged(object sender, EventArgs e)
{
    login.UseSystemPasswordChar = login.Text.StartsWith(<prefix-goes-here>);
}

private void login_Leave(object sender, EventArgs e)
{
    if (login.Text.StartsWith(<prefix-goes-here>) && login.Text.Length != 9)
    {
        signInError.SetError(login, "Your System ID must be nine digits.");
        login.BackColor = Color.LightPink;
    }
    else if (login.Text.IsNullOrWhiteSpace())
    {
        signInError.SetError(login, "Please enter your username or System ID.");
        login.BackColor = Color.LightPink;
    }
    else
    {
        signInError.SetError(login, string.Empty);
        login.BackColor = Color.White;
    }
}

最终,我不知道这会导致很多问题,我可以将此验证步骤移至表单上登录按钮的 Click 事件,但我会如果可能的话,而是逐个进行验证。

【问题讨论】:

  • 这对我来说也没有任何意义。我在 Visual Studio 中检查了调用堆栈,它显示 login_TextChanged 已调用 login_Leave。我已经多次检查设计器以确保没有与事件相关的其他任何东西,清理并重建了应用程序,但它仍然会发生。
  • 好的,看来关键细节——我忽略了,不知道这是一个关键细节——是这个 TextBox 控件位于 GroupBox 控件内。我将 TextBox 移到 GroupBox 控件之外,这些事件按预期触发。在 GroupBox 内部,它的作用与我上面描述的一样。

标签: c# winforms


【解决方案1】:

将 TextBox 放在 GroupBox 中确实会重现这种行为——这很奇怪。

如果你想保留你的 GroupBox,这里有一个解决方法:

private void login_TextChanged(object sender, EventArgs e)
{
  login.Leave -= login_Leave;
  login.UseSystemPasswordChar = login.Text.StartsWith(<prefix-goes-here>);
  login.Leave += login_Leave;
}

【讨论】:

    【解决方案2】:

    无论出于何种原因,当登录 TextBox 位于 GroupBox 控件中时,Leave 事件就会触发。将GroupBox 替换为简单的Label 控件可防止TextChanged 事件中的代码触发Leave 事件。

    【讨论】:

      【解决方案3】:

      是的,这是 UseSystemPasswordChar 属性的一个怪癖。它是创建本机编辑控件时必须指定的属性 (ES_PASSWORD)。更改它需要 Winforms 销毁该本机控件并重新创建它。这有副作用,其中之一是焦点不能停留在文本框上,因为窗口消失了。 Windows 触发 WM_KILLFOCUS 通知。

      在 GroupBox 中确实是必要的组成部分,Winforms 在收到通知时不会抑制 Leave 事件。错误。

      许多可能的修复。您可以设置一个标志,让 Leave 事件处理程序可以检查以了解它是由更改属性引起的。

      【讨论】:

      • 不,不是。 ES_PASSWORD 样式可以通过发送EM_SETPASSWORDCHAR 随时更改,并且不需要重新创建控制窗口。
      • 这与它在 Winforms 中的实现方式及其对 Win98 的支持有关。我不知道有谁如此渴望一再表明他的无知。
      • 也许 WinForms 确实重新创建了控制窗口,但 MSDN 说它不是必需的。您的回答使用了不准确的词 requiresmust(至少根据 Win32 文档)。其他仍然涵盖 Win95 的在线参考资料表明,这些操作系统也支持EM_SETPASSWORDCHAR
      猜你喜欢
      • 2013-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-04
      • 1970-01-01
      相关资源
      最近更新 更多