【问题标题】:Wondering about TextBox methods想知道 TextBox 方法
【发布时间】:2013-11-13 20:29:58
【问题描述】:

我有一个TextBox,我想根据其中是否输入整数来运行几个条件。我的操作发生在 TextBox 所在窗口的代码隐藏中。

LostFocus 事件下,我想做以下事情:

  • 检查string IsNullOrEmpty

    -如果是-将文本设置为“默认记录”

  • 验证输入的值是Int

    如果不是 - 显示 MessageBox(Ok Button),然后将焦点重新设置在 TextBox

**这是我的LostFocus 函数的样子:

private void TextBox_LostFocus(object sender, RoutedEventArgs e) //Lost Focus
{
    if (string.IsNullOrEmpty(TextBox.Text))
        TextBox.Text = "Default Record";
    else if (Regex.IsMatch(TextBox.Text, @"^\d+$") == false)
    {
        MessageBox.Show("Illegal character in list.", "Warning!", MessageBoxButton.OK, MessageBoxImage.Warning);
        TextBox.Focus();
    }
}

上述函数可以很好地测试string IsNullOrEmpty,但我遇到了else if 条件的问题。当我尝试将焦点重新设置回TextBox 时,我得到MessageBoxes 的无限循环。为什么会这样,我该如何解决?

更新 1:

这些是TextBox 上的附加事件处理程序:

//State of View at startup
private void Document_Loaded(object sender, RoutedEventArgs e)
{
    //This is run because I need the TextBox to have focus at window startup
    TextBox.Focusable = true;
    TextBox.Focus();
}

xaml:

<UserControl Loaded="Document_Loaded" ... >

【问题讨论】:

  • 文本框上是否有任何其他事件处理程序,或者此处理程序中未显示任何代码?
  • 是的,我有很多。如果我要发布所有内容,那就太多了。我应该寻找什么会破坏这个过程?
  • @Ericafterdark 开始一一删除它们,直到您想出复制问题所需的最小代码示例。当您删除任何剩余的事件处理程序或删除现有处理程序的任何部分时,会导致程序不再复制问题,那么您就有了“最小可重现代码示例”。在许多情况下,当你到达那一点时,问题就很明显了。如果不是,请编辑问题以包含它。
  • 好的,我创建了一个全新的程序,其中包含一个带有 2 TextBoxes 的窗口。整个窗口中唯一的事件处理程序是您在上面看到的LostFocus。话虽如此,我收到了相同的MessageBoxes 无限循环。也许您不能从LostFocus 事件处理程序调用.focus()...
  • 我能够复制它(有点 - 它只发生 3 次~)。 (Winforms)奇怪。

标签: c# wpf textbox code-behind lostfocus


【解决方案1】:

不要尝试从 Enter、GotFocus、Leave、 LostFocus、Validating 或 Validated 事件处理程序。这样做会导致 您的应用程序或操作系统停止响应...

来自MSDN

【讨论】:

  • 那么我应该如何根据离开TextBox的用户来进行这些操作?
  • @Ericafterdark 你不是。这才是重点。无论如何,阻止他们从文本框中移除焦点直到它被修复是非常糟糕的用户设计。只是阻止他们执行依赖于具有有效值的文本框的任何操作(即禁用相关按钮),而不是强制将焦点放在文本框上。
  • @Servy 我明白了。我将不得不重新设计一点,但这是有道理的。
【解决方案2】:

跟踪自您上次显示消息框以来该值是否已更改。 仅当自上次显示消息框后值发生更改时才显示消息框。

我是这样想的:

private string lastValue = null;
private void TextBox_LostFocus(object sender, RoutedEventArgs e) //Lost Focus
{
    bool valueChanged = ( lastvalue != TextBox.Text );
    lastValue = TextBox.Text;
    if (string.IsNullOrEmpty(TextBox.Text))
        TextBox.Text = "Default Record";
    else if (Regex.IsMatch(TextBox.Text, @"^\d+$") == false && valueChanged )
    {
        MessageBox.Show("Illegal character in list.", "Warning!", MessageBoxButton.OK, MessageBoxImage.Warning);
        TextBox.Focus();
    }
}

【讨论】:

  • 这可行,但它不会将焦点设置回textBox。 (线TextBox.Focus();
【解决方案3】:

当我尝试将焦点重新设置回 TextBox 时,我得到了无穷无尽的 MessageBoxes的循环

发生这种情况是因为您正在调用 TextBox 控件的焦点,就在引发事件 LostFocus 时。当您关闭 MessageBox 时,TextBox 控件获得焦点,但事件 LostFocus 不断引发,并且由于满足 else 条件,您将与 MessageBoxes 进行无限循环。

我认为您不应该使用事件LostFocus 来检查TextBox 的值并再次聚焦。你考虑过TextChanged这个事件吗?

然后你可以这样做:

private void TextTest_TextChanged(object sender, TextChangedEventArgs e)
{
      Console.WriteLine("Text changed");

      /*  your logic here */   

      TextTest.Focus(); //it could be useless in this case!
}

【讨论】:

  • 上面写着your logic here,我需要改变什么吗?
  • 首先,这不会导致堆栈溢出异常。堆栈没有增加。它只是永远。接下来,显示的代码没有说明设置焦点如何导致焦点再次丢失,这需要发生才能有一个无限循环。
  • @Servy 是的,你是对的。我测试了一段错误的代码。我的错。我的答案已更新。
  • @Ericafterdark 您应该用您的逻辑替换评论,用于检查用户在您的 TextBox 中的输入。
  • @AlbertoSolano 仍然不对。如果您在失去焦点时设置焦点,那么您将永远无法聚焦其他任何东西(当然,这是糟糕的用户设计),但除非再次聚焦对象导致焦点丢失,否则不会再次触发“失去焦点”处理程序,所以没有循环。循环不是显示的代码中固有的。
【解决方案4】:

您可能还想查看使用屏蔽文本框将输入限制为整数。然后你想在用户点击“ok/next/submit”时进行验证(检查)......无论什么都会完成条目。

http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask%28v=vs.90%29.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-28
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 2019-05-25
    • 2019-03-13
    相关资源
    最近更新 更多