I'm trying to get WPF validation to work within the MVVM pattern.
In my View, I can validate a TextBox like this which gets handled by the code-behind method "HandleError", 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 the validation in my ViewModel via a DelegateCommand but when I try it with the following code, I get the explicit error "'{Binding HandleErrorCommand}' is not a valid event handler method name. Only instance methods on the generated or code-behind class are valid."
Are there any workaround for this so that we can handle validations within a 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
I don't know if this will help you, but I'll offer it all the same.
Also, I'm using Silverlight, not WPF.
I don't specify any validation in my Views, neither in the code behind nor the xaml. My View has only data bindings to properties on the ViewModel.
All my error checking/validation is handled by the ViewModel. When I encounter an error, I set a ErrorMessage property, which is bound to the view as well. The ErrorMessage textblock (in the view) has a value converter which hides it if the error is null or empty.
Doing things this way makes it easy to unit test input validation.
Here's a way to do this using Expression Blend 3 behaviors. I wrote a ValidationErrorEventTrigger because the built-in EventTrigger doesn't work with attached events.
View:
ViewModel: (could be unchanged, but here's a look at how I dug into the validation arguments to find the error message when using the exception validation rule)
ValidationErrorEventTrigger: