I have a desktop app developed with WPF in .net framework 4 and trying to set up my field validation with MVVM. I have implemented INotifyDataErrorInfo interface on my EntryClass which is being used inside MainWindowViewModel.
The interface implementation is done so my properties are not validated on propertychange inside set{} but rather after a user click 'Save' button.
public bool IsFormValid()
{
bool valid = true;
_errorHandler.ClearAllErrors();
if (BrojTransakcije==null || BrojTransakcije.Length<4)
{
_errorHandler.AddError(nameof(BrojTransakcije), "Invalid chars");
valid = false;
}
return valid;
}
And it works, after clicking'save' I first clear all of the properties ( and raise ErrorsChanged() ) check the property and if it is invalid the error is shown on the view.
private void RaiseErrorChanged(string propertyName)
{
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
public void ClearAllErrors()
{
_formGreske.Clear();
RaiseErrorChanged(string.Empty); //reset everything
}
The problem I am having is: after the user inputs the correct value, the validation passes but the error info still stays on the screen, its not updating. If a user appends something on that input and clicks 'Save' again the error dissapears.
I have narrowed it down that the view (the binding engine I suppose) is not calling the GetErrors() method of the interface and it does not understand that the errors are cleared. Is there a way to force the view(binding engine) to forcely GetErrors() because obviously is not doing that?
<StackPanel>
<Label Style="{StaticResource LabelTitles}"
Content="Broj transakcije"></Label>
<TextBox Style="{StaticResource InputBox}"
Text="{Binding NoviUnos.BrojTransakcije,
ValidatesOnNotifyDataErrors=True}">
</TextBox>
</StackPanel>
CodePudding user response:
If you are triggering the validation on Save (eg not in your set{}) then the only time it knows to validate is when you click save again.
I would add some logic to your set; to so it validates on LostFocus personally
Also just as a general note in case you haven't heard of it the 'mvvm community toolkit' is amazing for this stuff. Using the ObservableValidator class does a lot of the hard work for you https://learn.microsoft.com/en-us/windows/communitytoolkit/mvvm/observablevalidator
CodePudding user response:
Is there a way to force the view(binding engine) to forcely GetErrors() ...?
Implement INotifyPropertyChanged
and raise the PropertyChanged
event for the data-bound source property (BrojTransakcije
). See this answer for more information.