Given is an Wpf .Net5.0 Application with an Resetbutton and Textbox
Reset set path to Defalut
Command="{Binding ResetCommand}" ... FilePath = @"C:\Temp";
Textbox: User can edit Path
Text="{Binding FilePath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True}"
private string _filePath;
public string FilePath
{
get => _filePath;
set
{
var r = new Regex(@"[\w\s\\.:\-!~]");
if (r.Matches(value).Count == value.Length)
{
SetProperty(ref _filePath, value);
return;
}
throw new ArgumentException("Not an valid windows path");
}
}
When the path is valid I can reset to Default. UI Updates When user enter an invalid character the border turns red and the Reset button not updating UI.
I try to debug by Snoop and its look like the VM is reseting. But not UI. What is wrong?
Working Demo: https://github.com/LwServices/WpfValidationDemo/tree/master/ValidationWpf
you can solve it by notifying your UI directly after set the value
private void Reset()
{
FilePath = @"C:\Temp";
OnPropertyChanged(nameof(FilePath));
}
when the Filepath
is not matching your Regex, you just raise an exception without modifying the value of _filePath
and it will be always valid path
public string FilePath
{
get => _filePath;
set
{
var r = new Regex(@"[\w\s\\.:\-!~]");
if (r.Matches(value).Count == value.Length)
{
SetProperty(ref _filePath, value); //<<<<<< this will never call if the value passed from the ui doesnot match Regex
return;
}
throw new ArgumentException("Not an valid windows path");
}
}
when you call reset()
you try to set Filepath
to c:/temp and if the last value of _filePath
is equal to c:/temp the problem will be appear from the following
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false; /// your code will return
field = value;
OnPropertyChanged(propertyName); // before notify the UI
return true;
}
so as suggested in the beginning the simple solution is to notify your UI directly OR delete the check line from SetProperty
method
if (EqualityComparer<T>.Default.Equals(field, value)) return false;