我有下面的WPF文本框:
<TextBox Grid.Column="0"
Grid.Row="1"
Text="{Binding myPath, UpdateSourceTrigger=PropertyChanged}"
Margin="5,8,8,5" />
它在视图模型中的属性是:
public string myPath
{
get => myObject.path;
set
{
// Do some comprobations before assigning the new value
if (comprobationsOk(value))
{
Uri myUri = new Uri(value);
myObject.path = myUri.LocalPath;
this.OnPropertyChanged();
}
}
}
这是ViewModelBase类中的OnPropertyChanged方法,它实现了INotifyPropertyChanged:
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
正如您所看到的,实际的视图模型值在setter中进行了转换。
当用户开始在TextBox///my/absolute/path
中键入时,视图模型中的属性将获得//my/absolute/path
所以我希望TextBox
更新为//my/absolute/path
,但它不是,并且保持为///my/absolute/path
实际上,它与工作视图模型配合得很好。
视图:
<TextBox Text="{Binding Path, UpdateSourceTrigger=PropertyChanged}" />
查看模型:
public class ViewModel : NotifyPropertyChangedBase
{
private string _name = string.Empty;
public string Path
{
get => _name;
set
{
// To avoid constant System.UriFormatException, we use the try method
var newValue = Uri.TryCreate(value, UriKind.Absolute, out var result) ? result.LocalPath : value;
Update(ref _name, newValue);
}
}
}
NotifyPropertyChangedBase:
public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void Update<T>(ref T field, T newValue, [CallerMemberName] string? propertyName = null)
{
if (Equals(field, newValue))
return;
field = newValue;
OnPropertyChanged(propertyName);
}
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}