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
CodePudding user response:
Simple solution
you can solve it by notifying your UI directly after set the value
private void Reset()
{
FilePath = @"C:\Temp";
OnPropertyChanged(nameof(FilePath));
}
reason of the problem
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;
CodePudding user response:
its disabling due to missing CanExecute method, use below code
internal class MainWindowViewModel : NotifyPropertyChanged {
private DelegateCommand _resetCmd;
public ICommand ResetCommand => _resetCmd ?? new DelegateCommand(Reset, canRest);
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");
}
}
public MainWindowViewModel()
{
}
private void Reset(object obj)
{
FilePath = @"C:\Temp";
}
private bool canRest() {
return true;
}
}