使用WPFvalidation规则并禁用“保存”button

我有一个页面,点击保存button之前,几个文本框不能为空。

<TextBox... <TextBox.Text> <Binding Path ="LastName" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:StringRequiredValidationRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> 

我的规则起作用。 我在我的文本框周围有一个红色的边框,直到我input一个值。 所以现在我想将这个validation规则添加到我的其他文本框。

现在,如何禁用保存button,直到页面没有错误? 我不知道要检查是否有任何validation错误。

在视图的代码隐藏你可以像这样连接Validation.ErrorEvent;

 this.AddHandler(Validation.ErrorEvent,new RoutedEventHandler(OnErrorEvent)); 

接着

 private int errorCount; private void OnErrorEvent(object sender, RoutedEventArgs e) { var validationEventArgs = e as ValidationErrorEventArgs; if (validationEventArgs == null) throw new Exception("Unexpected event args"); switch(validationEventArgs.Action) { case ValidationErrorEventAction.Added: { errorCount++; break; } case ValidationErrorEventAction.Removed: { errorCount--; break; } default: { throw new Exception("Unknown action"); } } Save.IsEnabled = errorCount == 0; } 

这使得假设你会得到删除的通知(如果你删除了无效的元素,这种情况不会发生)。

你想使用Validation.HasError附加属性。

沿着同样的线路乔希·史密斯有一个有趣的阅读绑定到(Validation.Errors)[0]没有创builddebugging的发言 。

 int count = 0; private void LayoutRoot_BindingValidationError(object sender, ValidationErrorEventArgs e) { if (e.Action == ValidationErrorEventAction.Added) { button1.IsEnabled = false; count++; } if (e.Action == ValidationErrorEventAction.Removed) { count--; if (count == 0) button1.IsEnabled = true; } } 

这是跟踪依赖对象(及其所有子对象)上的validation错误的辅助方法,并调用委托通知有关更改。 它还跟踪删除有validation错误的儿童。

  public static void AddErrorHandler(DependencyObject element, Action<bool> setHasValidationErrors) { var errors = new List<Tuple<object, ValidationError>>(); RoutedEventHandler sourceUnloaded = null; sourceUnloaded = (sender, args) => { if (sender is FrameworkElement) ((FrameworkElement) sender).Unloaded -= sourceUnloaded; else ((FrameworkContentElement) sender).Unloaded -= sourceUnloaded; foreach (var error in errors.Where(err => err.Item1 == sender).ToArray()) errors.Remove(error); setHasValidationErrors(errors.Any()); }; EventHandler<ValidationErrorEventArgs> errorHandler = (_, args) => { if (args.Action == ValidationErrorEventAction.Added) { errors.Add(new Tuple<object, ValidationError>(args.OriginalSource, args.Error)); if (args.OriginalSource is FrameworkElement) ((FrameworkElement)args.OriginalSource).Unloaded += sourceUnloaded; else if (args.OriginalSource is FrameworkContentElement) ((FrameworkContentElement)args.OriginalSource).Unloaded += sourceUnloaded; } else { var error = errors .FirstOrDefault(err => err.Item1 == args.OriginalSource && err.Item2 == args.Error); if (error != null) errors.Remove(error); } setHasValidationErrors(errors.Any()); }; System.Windows.Controls.Validation.AddErrorHandler(element, errorHandler); } 

这是你需要检查代码行为的HasError控制属性

并在保存button点击做这个代码

  BindingExpression bexp = this.TextBox1.GetBindingExpression(TextBox.TextProperty); bexp.UpdateSource(); // this to refresh the binding and see if any error exist bool hasError = bexp.HasError; // this is boolean property indique if there is error MessageBox.Show(hasError.ToString()); 

我已经尝试了上面提到的几个解决scheme。 但是,他们没有一个为我工作。

我的简单问题

我有一个简单的input窗口,请求来自用户的URI,如果TextBox值不是有效的Uri那么Okaybutton应该被禁用。

我的简单解决scheme

这是什么对我有用:

 CommandBindings.Add(new CommandBinding(AppCommands.Okay, (sender, args) => DialogResult = true, (sender, args) => args.CanExecute = !(bool) _uriTextBoxControl.GetValue(Validation.HasErrorProperty))); 

只是从System.ComponentModel.IDataErrorInfo inhert您的ViewModelvalidation和从INotifyPropertyChanged通知button

使财产:

  public bool IsValid { get { if (this.FloorPlanName.IsEmpty()) return false; return true; } } 

在xaml中,将其连接到button

 <Button Margin="4,0,0,0" Style="{StaticResource McVMStdButton_Ok}" Click="btnDialogOk_Click" IsEnabled="{Binding IsValid}"/> 

在IDataErrorInfo中覆盖,通知btutton

 public string this[string columnName]{ get { switch (columnName) { case "FloorPlanName": if (this.FloorPlanName.IsEmpty()) { OnPropertyChanged("IsValid"); return "Floor plan name cant be empty"; } break; } } }