将WPF验证集成到MVVM中

本文关键字:MVVM 集成 WPF 验证 | 更新日期: 2023-09-27 17:57:46

我有一些有效的ValidationRules。我只是想知道将它与我的ViewModel集成的最佳方式是什么。

我有一个(过于简单)的方法——HasAnyErrors——它遍历控制树,检查错误,但我不知道如何将这些结果公开给我的ViewModel。换句话说,如果我有一个只有在没有验证错误的情况下才能执行的ICommand,我该怎么办?

我能想到的最好的办法就是处理按钮的点击事件,然后在没有错误的情况下手动调用ViewModel的命令。

    private void Button_Click_RunCommand(object sender, RoutedEventArgs e) {
        if (this.HasAnyErrors())
            return;
        (this.DataContext as SomeViewModel).SomeCommand.Execute(null);
    }

这不是最优雅的解决方案;但它似乎奏效了。有没有更优雅的解决方案?

中断

为了完整起见,下面是验证方法(不久之后大多数都是扩展方法)。它们(看起来)工作得很好,但我相信至少有人会想知道它们是什么样子的。

    bool HasAnyErrors() {
        List<string> errors = new List<string>();
        GetErrors(this, errors);
        return errors.Any();
    }
    void GetErrors(DependencyObject obj, List<string> errors) {
        foreach (UIElement child in LogicalTreeHelper.GetChildren(obj).OfType<UIElement>()) {
            if (child is TextBox)
                AddErrorIfExists(child as UIElement, errors);
            GetErrors(child, errors);
        }
    }
    private void AddErrorIfExists(UIElement element, List<string> errors) {
        if (Validation.GetHasError(element))
            errors.Add(Validation.GetErrors(element)[0].ErrorContent.ToString());
    }

将WPF验证集成到MVVM中

假设您可以确定它们是否是针对视图模型本身的任何验证方法,而不是使用Validation.GetErrors()——如果您正在实现IDataErrorInfo,那么它可能会更简单。

如果是这种情况,则可以在按钮绑定到的命令的CanExecute方法中考虑视图模型的验证状态。

您可能对WPF应用程序框架(WAF)BookLibrary示例应用程序感兴趣。BookView.xaml.cs类展示了如何将WPF验证状态与底层ViewModel同步。

在示例中,它用于解析错误。在这种具体情况下,当用户在Pages TextBox中输入"abc"时,会出现解析错误。页面绑定到一个整数值,因此无法解析"abc"。