Val"/>

WPF中的强大验证

WPF中的强大验证

Strong Validation in WPF

我的应用程序中有一个数据绑定文本框,如下所示:(Height的类型为decimal?)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<TextBox Text="{Binding Height, UpdateSourceTrigger=PropertyChanged,
                        ValidatesOnExceptions=True,
                        Converter={StaticResource NullConverter}}" />

public class NullableConverter : IValueConverter {
    public object Convert(object o, Type type, object parameter, CultureInfo culture) {
        return o;
    }

    public object ConvertBack(object o, Type type, object parameter, CultureInfo culture) {
        if (o as string == null || (o as string).Trim() == string.Empty)
            return null;
        return o;
    }
}

通过这种方式配置,任何不能转换为十进制的非空字符串都会导致验证错误,该错误将立即突出显示文本框。 但是,TextBox仍会失去焦点并保持无效状态。 我想做的是:

  • 在文本框包含有效值之前,不要让它失去焦点。
  • 将文本框中的值还原为最后一个有效值。
  • 做这个的最好方式是什么?

    更新:

    我找到了一种方法来做#2。 我不喜欢它,但是它有效:

    1
    2
    3
    4
    5
    6
    private void TextBox_LostKeyboardFocus(object sender, RoutedEventArgs e) {
        var box = sender as TextBox;
        var binding = box.GetBindingExpression(TextBox.TextProperty);
        if (binding.HasError)
            binding.UpdateTarget();
    }

    有谁知道如何做得更好? (或执行#1。)


    您可以通过处理PreviewLostKeyBoardFocus事件来强制键盘焦点停留在TextBox上,如下所示:

    1
    2
    3
    4
    5
     <TextBox PreviewLostKeyboardFocus="TextBox_PreviewLostKeyboardFocus" />

     private void TextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) {
         e.Handled = true;
     }

    在我看来,您将要处理两个事件:

    GotFocus:当文本框获得焦点时将触发。 您可以存储框的初始值。

    LostFocus:当文本框失去焦点时将触发。 此时,您可以进行验证并决定是否要回滚。


    推荐阅读