How can I handle Validation.Error in my ViewModel instead of my view code?

I am trying to get WPF validation to work in the MVVM pattern.

In my view, I can check for a TextBox like this, which is handled by the "HandleError" code method, which works fine:

<TextBox Width="200" Validation.Error="HandleError"> <TextBox.Text> <Binding Path="FirstName" NotifyOnValidationError="True" Mode="TwoWay"> <Binding.ValidationRules> <validators:DataTypeLineIsValid/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> 

However, I would like to handle validation in my ViewModel using DelegateCommand, but when I try it with the following code, I get an explicit error " '{Binding HandleErrorCommand}' is not a valid name event handler method. Only valid class methods the generated code or code is valid. "

Is there any workaround for this so that we can handle validations in the MVVM pattern?

View:

 <TextBox Width="200" Validation.Error="{Binding HandleErrorCommand}"> <TextBox.Text> <Binding Path="FirstName" NotifyOnValidationError="True" Mode="TwoWay"> <Binding.ValidationRules> <validators:DataTypeLineIsValid/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> 

ViewModel:

 #region DelegateCommand: HandleError private DelegateCommand handleErrorCommand; public ICommand HandleErrorCommand { get { if (handleErrorCommand == null) { handleErrorCommand = new DelegateCommand(HandleError, CanHandleError); } return handleErrorCommand; } } private void HandleError() { MessageBox.Show("in view model"); } private bool CanHandleError() { return true; } #endregion 
+4
c # validation wpf mvvm
source share
3 answers

I don’t know if this will help you, but I suggest anyway.

In addition, I use Silverlight, not WPF.

I do not indicate any validations in my submissions, neither in code nor in xaml. My view has only data bindings to properties in the ViewModel.

All my error checking / checking is handled by ViewModel. When I encounter an error, I set the ErrorMessage property, which is also associated with the view. The ErrorMessage text block (in the view) has a value converter that hides it if the error is empty or empty.

Running this method makes it easy to validate the unit test input.

+9
source share

You can do this here using Expression Blend 3 behavior. I wrote a ValidationErrorEventTrigger because the built-in EventTrigger does not work with nested events.

View:

 <TextBox> <i:Interaction.Triggers> <MVVMBehaviors:ValidationErrorEventTrigger> <MVVMBehaviors:ExecuteCommandAction TargetCommand="HandleErrorCommand" /> </MVVMBehaviors:ValidationErrorEventTrigger> </i:Interaction.Triggers> <TextBox.Text> <Binding Path="FirstName" Mode="TwoWay" NotifyOnValidationError="True"> <Binding.ValidationRules> <ExceptionValidationRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> 

ViewModel: (cannot be changed, but look at how I delved into the validation arguments to find the error message when using the exception validation rule)

  public ICommand HandleErrorCommand { get { if (_handleErrorCommand == null) _handleErrorCommand = new RelayCommand<object>(param => OnDisplayError(param)); return _handleErrorCommand; } } private void OnDisplayError(object param) { string message = "Error!"; var errorArgs = param as ValidationErrorEventArgs; if (errorArgs != null) { var exception = errorArgs.Error.Exception; while (exception != null) { message = exception.Message; exception = exception.InnerException; } } Status = message; } 

ValidationErrorEventTrigger:

 public class ValidationErrorEventTrigger : EventTriggerBase<DependencyObject> { protected override void OnAttached() { Behavior behavior = base.AssociatedObject as Behavior; FrameworkElement associatedElement = base.AssociatedObject as FrameworkElement; if (behavior != null) { associatedElement = ((IAttachedObject)behavior).AssociatedObject as FrameworkElement; } if (associatedElement == null) { throw new ArgumentException("Validation Error Event trigger can only be associated to framework elements"); } associatedElement.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(this.OnValidationError)); } void OnValidationError(object sender, RoutedEventArgs args) { base.OnEvent(args); } protected override string GetEventName() { return Validation.ErrorEvent.Name; } } 
+6
source share

Events are complex with MVVM but not impossible. A typical method is to use bound behavior to handle this. Caliburn has a useful solution for this in Message.Attach behavior.

0
source share

All Articles