WPF TextBox.Focus() 的烦恼

标签 wpf textbox focus

我对 .Net 和 WPF 很陌生,遇到了问题。代码是一个片段。我有 TextBox es 输入日期。我使用 GotFocus 检查正确的输入和 LostFocus事件。

<TextBox Name="sdDay" Width="40" Text="Day" GotFocus="DateDay_GotFocus" LostFocus="DateDay_LostFocus" Padding="5,5,5,5" HorizontalContentAlignment="Center" Focusable="True"/>
<TextBox Name="sdMonth" Width="50" Text="Month" GotFocus="DateMonth_GotFocus" LostFocus="DateMonth_LostFocus" Padding="5,5,5,5" Margin="5,0,0,0" HorizontalContentAlignment="Center" Focusable="True"/>
<TextBox Name="sdYear" Width="50" Text="Year" GotFocus="DateYear_GotFocus" LostFocus="DateYear_LostFocus" Padding="5,5,5,5" Margin="5,0,0,0" HorizontalContentAlignment="Center" Focusable="True"/>

和代码:
private void DateDay_GotFocus(object sender, RoutedEventArgs e)
    {
        if (((TextBox)sender).Text == "Day")
            ((TextBox)sender).Text = string.Empty;
    }

private void DateDay_LostFocus(object sender, RoutedEventArgs e)
    {
        if (((TextBox)sender).Text == string.Empty)
            ((TextBox)sender).Text = "Day";
        else
            CheckForCorrectDateDay((TextBox)sender);
    }

private void CheckForCorrectDateDay(TextBox b)
    {
        int day = 0;

        try
        {
            day = int.Parse(b.Text);

            if (day < 0 || day > 31)
            {
                MessageBox.Show("Please enter a correct day.");
                b.Text = string.Empty;
                b.Focus();
            }
        }
        catch (FormatException)
        {
            MessageBox.Show("Please enter a number.", "Incorrect Input", MessageBoxButton.OK, MessageBoxImage.Warning);
            b.Text = string.Empty;
            b.Focus();
        }
        catch (Exception)
        {
            throw;
        }
    }

现在我想要它做的是检查输入是否正确,如果失败,将焦点设置回任何 TextBox输入不正确。

但它不起作用。在我输入超出范围(或字母)的数字后,MessageBox将显示,但焦点转移到下一个用于输入月份的文本框。

我究竟做错了什么?

最佳答案

坦率地说,您的验证技术非常差。也就是说,我认为问题只是在您设置焦点后 WPF 正在处理选项卡,因此它将焦点设置回焦点顺序中的下一个项目。

一个简单的解决方法是发送在当前消息之后处理的单独消息:

if (day < 0 || day > 31)
{
    MessageBox.Show("Please enter a correct day.");
    b.Text = string.Empty;

    Dispatcher.BeginInvoke((ThreadStart)delegate
    {
        b.Focus();
    });
}

这样做可确保 WPF 完全处理 LostFocus事件处理程序在处理单独的消息以将焦点设置在错误控件上之前。

就如何以更好的方式解决此问题而言,您可以:
  • 定义具有日、月和年属性的 View 模型(先决条件:阅读 MVVM 模式)
  • 实现IDataErrorInfo在 View 模型
  • 绑定(bind)TextBox es 在 UI 中到 View 模型上的相应属性(先决条件:阅读 WPF 数据绑定(bind))
  • 关于WPF TextBox.Focus() 的烦恼,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1211876/

    相关文章:

    WPF TextBox - 以编程方式选择文本,同时保留 "selection direction"

    c# - 如何在不使用 ajax 扩展或 Web 服务的情况下在文本框中提供自动完成功能?

    android - 调用 setVisibility(View.VISIBLE) 时不改变焦点

    java - 无法聚焦 JScrollPane?

    c# - 只读值的优雅解决方案

    c# - c# WPF 中的 idataerrorinfo

    C# 使用反射访问窗口属性

    c# - 根据两个列表框之一中的选择更改 ContentControl 的绑定(bind)

    python - 如何从 python pptx 生成的幻灯片中删除空白文本框?

    html - 带有本地 HTML 文件的 IE 焦点