WPF数据绑定exception处理

我有一个绑定到Integer属性的文本框。 当用户在文本框中输入无法转换为整数(例如名称)的内容时,将抛出exception并且原始属性值不会更改。 我想捕获exception,以便我可以禁用连接到该属性的命令? 我怎么能这样做,如果可能的话,从定义属性的视图模型?

考虑从视图模型而不是从视图调用命令。

private int _myProperty; public int MyProperty { get { return _myProperty; } set { _myProperty = value; // See if the value can be parsed to an int. int potentialInt; if(int.TryParse(_myProperty, out potentialInt)) { // If it can, execute your command with any needed parameters. yourCommand.Execute(_possibleParameter) } } } 

这将允许您处理用户键入无法解析为整数的内容,并且只有在用户键入的是整数时才会触发该命令。

(我没有测试此代码,但我认为它可能会有所帮助。)

我最近遇到了同样的问题,并且我使用了行为来解决它(但是如果你不想要它就不需要它们,它只是为了重用我在不同视图中需要的代码)。 主要思想是在ViewModel中定义一些方法,允许视图通知ViewModel无法检测到的输入中的错误。

因此,首先在ViewModel中定义这些方法。 为简单起见,我只会跟踪错误的数量,但您可以存储更多关于它们的信息(如实际错误):

 private int _errorCount = 0; void AddUIValidationError() { _errorCount++; } void RemoveUIValidationError() { _errorCount--; } 

然后,在View中,注册System.Windows.Controls.Validation.ErrorEvent ,这是一个路由事件,可以让您知道组件(先前配置为通知数据错误)何时检测到错误(如exceptionvalidation错误):

 public partial class MyView : UserControl // or whatever it is { public MyView(MyViewModel viewModel) { // Possibly ensure that viewModel is not null InitializeComponent(); _myViewModel = viewModel; this.AddHandler(System.Windows.Controls.Validation.ErrorEvent, new RoutedEventHandler(OnValidationRaised)); } private MyViewModel _myViewModel; private void OnValidationRaised(object sender, RoutedEventArgs e) { var args = (System.Windows.Controls.ValidationErrorEventArgs)e; if (_myViewModel != null) { // Check if the error was caused by an exception if (args.Error.RuleInError is ExceptionValidationRule) { // Add or remove the error from the ViewModel if (args.Action == ValidationErrorEventAction.Added) _myViewModel.AddUIValidationError(); else if (args.Action == ValidationErrorEventAction.Removed) _myViewModel.RemoveUIValidationError(); } } } } 

在Command的CanExecute方法中,您将检查ViewModel的_errorCount字段是否大于0,在这种情况下,应该禁用该命令。

请注意,您必须将ValidatesOnExceptions=True, NotifyOnValidationError=True到绑定中,以便这可以工作。 例如:

  

编辑:

另一种方法,除了Riley提到的(这也很好,但要求你将模型中的每个整数属性映射到ViewModel中的新字符串属性)都使用ValidationRules。 您可以添加在解析和调用属性setter之前检查的ValidationRule 。 因此,您可以inheritanceValidationRule并实现Validate方法,以确保可以将字符串解析为整数。 例:

 public class IntegerValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { int number; if(Int32.TryParse((string)value, out number) == false) return new ValidationResult(false, "It is not a valid number"); return new ValidationResult(true, null); } } 

然后,在您的视图中定义名称空间,其中定义了IntegerValidationRule:

  

并在绑定中使用规则:

          

但无论如何,您需要为要validation的每个非字符串类型创建类,我认为Binding语法现在看起来有点长。

问候

本文为您提供了非常深入的答案,并提供了源代码: http : //karlshifflett.wordpress.com/2008/04/03/wpf-sample-series-handling-and-reporting-wpf-data-结合validation-错误-和-例外/

我在网上找到的“最佳”解决方案在http://www.wpfsharp.com/2012/02/03/how-to-disable-a-button-on-textbox-validationerrors-in-wpf中有解释。 /

简而言之,validation错误在View中处理,而不是在ViewModel中处理。 您不需要自己的ValidationRule。 只需在XAML中为按钮添加样式:

    

希望这可以帮助那些偶然发现这个问题的人(我知道这么多年后它不会对OP有所帮助)。