WPF TextBox.Focus()烦恼

时间:2009-07-31 10:43:28

标签: wpf textbox focus

我对.Net和WPF很新,但有问题。代码是一个片段。我有TextBox es来输入日期。我使用GotFocusLostFocus事件检查了正确的输入。

<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将显示,但焦点将转移到下一个用于输入月份的TextBox。

我做错了什么?

1 个答案:

答案 0 :(得分:14)

坦率地说,你的验证技术非常差。也就是说,我认为问题只是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事件处理程序,以便将注意力集中在错误的控件上。

就如何以更好的方式解决这个问题而言,你可以:

  1. 定义包含日,月和年属性的视图模型(先决条件:阅读MVVM模式)
  2. 在视图模型上实施IDataErrorInfo
  3. 将UI中的TextBox绑定到视图模型上的相应属性(先决条件:阅读WPF数据绑定)