Home > OS >  On ValidatesOnExceptions UI is not updating
On ValidatesOnExceptions UI is not updating

Time:10-12

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;
    }
}
  • Related