Usando las reglas de validación de WPF y deshabilitando un botón ‘Guardar’

Tengo una página donde algunos cuadros de texto no pueden estar vacíos antes de hacer clic en un botón Guardar.

<TextBox...        

Mi regla funciona Tengo un borde rojo alrededor de mi cuadro de texto hasta que ingrese un valor. Así que ahora quiero agregar esta regla de validación a mis otros cuadros de texto.

Ahora, ¿cómo desactivo el botón Guardar hasta que la página no tenga errores? No sé qué revisar para ver si hay algún error de validación.

En el código detrás de la vista, puede conectar el Validation.ErrorEvent como tal;

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

Y entonces

 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; } 

Esto supone que se te notificará la eliminación (lo que no sucederá si eliminas el elemento infractor mientras no sea válido).

Desea usar la propiedad adjunta Validation.HasError .

En la misma línea, Josh Smith tiene una lectura interesante sobre Binding to (Validation.Errors) [0] sin crear Debug Spew .

 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; } } 

Aquí hay un método auxiliar que rastrea los errores de validación en los objetos de dependencia (y todos sus elementos secundarios) y las llamadas delegadas para notificar sobre el cambio. También rastrea la eliminación de los niños con errores de validación.

  public static void AddErrorHandler(DependencyObject element, Action setHasValidationErrors) { var errors = new List>(); 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 errorHandler = (_, args) => { if (args.Action == ValidationErrorEventAction.Added) { errors.Add(new Tuple(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); } 

esto es lo que necesita para verificar la propiedad de control HasError del código behaind

y haga este código en el botón Guardar, haga clic

  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()); 

solo en su ViewModel de System.ComponentModel.IDataErrorInfo para Validate y de INotifyPropertyChanged para notificar el botón

hacer propiedad:

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

en xaml, conéctelo al botón

  

en las anulaciones de IDataErrorInfo, notifique 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; } } } 

He intentado varias de las soluciones indicadas anteriormente; sin embargo, ninguno de ellos funcionó para mí.

Mi problema simple

Tengo una ventana de entrada simple que solicita un URI del usuario, si el valor de TextBox no es un Uri válido, entonces el botón Aceptar debería estar deshabilitado.

Mi solución simple

Esto es lo que funcionó para mí:

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