Usando regras de validação do WPF e desabilitando o botão ‘Salvar’

Eu tenho uma página onde algumas checkboxs de texto não podem estar vazias antes de clicar em um botão Salvar.

<TextBox...        

Minha regra funciona. Eu tenho uma borda vermelha em torno da minha checkbox de texto até inserir um valor. Então agora eu quero adicionar essa regra de validação para minhas outras checkboxs de texto.

Agora, como desativo o botão Salvar até que a página não tenha erros? Eu não sei o que verificar para ver se há algum erro de validação.

No codebehind para a visão você poderia wireup o Validation.ErrorEvent como assim;

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

E depois

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

Isso pressupõe que você será notificado da remoção (o que não acontecerá se você remover o elemento ofensivo enquanto ele for inválido).

Você deseja usar a propriedade anexada Validation.HasError .

Na mesma linha, Josh Smith tem uma leitura interessante sobre Vinculação a (Validation.Errors) [0] sem a criação de 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; } } 

Aqui está um método auxiliar que rastreia erros de validação nos objects de dependência (e todos os seus filhos) e chama o delegado para notificar sobre a alteração. Também rastreia a remoção dos filhos com erros de validação.

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

é isso que você precisa verificar a propriedade de controle HasError do código behaind

e fazer este código no botão salvar clique

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

apenas herda seu ViewModel de System.ComponentModel.IDataErrorInfo para Validate e de INotifyPropertyChanged para o botão notify

faça a propriedade:

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

no xaml, conecte-o ao botão

  

nas substituições 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; } } } 

Eu tentei várias das soluções indicadas acima; no entanto, nenhum deles funcionou para mim.

Meu problema simples

Eu tenho uma janela de input simples que solicitar um URI do usuário, se o valor TextBox não é um Uri válido, em seguida, o botão Okay deve ser desativado.

Minha solução simples

Aqui está o que funcionou para mim:

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