给定的是一个Wpf .Net5.0应用程序带有重置按钮和文本框
-
将设置路径重置为默认值
Command="{Binding ResetCommand}" ... FilePath = @"C:Temp";
-
文本框:用户可以编辑路径
Text="{Binding FilePath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True}"
private string _filePath; public string FilePath { get => _filePath; set { var r = new Regex(@"[ws\.:-!~]"); if (r.Matches(value).Count == value.Length) { SetProperty(ref _filePath, value); return; } throw new ArgumentException("Not an valid windows path"); } }
当路径有效时,我可以重置为默认。UI更新当用户输入无效字符时,边框变为红色,Reset按钮不更新UI。
我试着用Snoop调试,它看起来像VM正在重置。但不是UI。怎么了?
工作演示:https://github.com/LwServices/WpfValidationDemo/tree/master/ValidationWpf
简单解决方案
你可以通过在设置值
后直接通知UI来解决这个问题private void Reset()
{
FilePath = @"C:Temp";
OnPropertyChanged(nameof(FilePath));
}
原因的问题当Filepath
不匹配您的Regex时,您只需在不修改_filePath
的值的情况下引发异常,并且它将始终是有效路径
public string FilePath
{
get => _filePath;
set
{
var r = new Regex(@"[ws\.:-!~]");
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");
}
}
当你调用reset()
时,你试图将Filepath
设置为c:/temp如果_filePath
的最后一个值等于c:/temp问题将从以下
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;
}
如开头所建议的,简单的解决方案是直接通知UI或删除SetProperty
方法中的检查行
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
由于缺少CanExecute方法而禁用,使用下面的代码
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(@"[ws\.:-!~]");
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;
}
}