我不是XAML
和MVVM
专家。我想知道,在所有最新的C#
改进中,我们是否仍然被迫像这样编写我们的MVVM
属性:
private string sessionName;
public string SessionName
{
get
{
return sessionName;
}
private set
{
sessionName = value;
NotifyPropertyChanged(nameof(SessionName));
}
}
还是有更好的方法可以做到这一点?
可以使用 Fody 自动将引发PropertyChanged
事件的代码注入到在编译时实现INotifyPropertyChanged
的类的属性库中。
然后,您可以像这样实现您的属性:
public string SessionName { get; set; }
不过,C# 语言本身或 UI 框架中没有任何内容可以使您不必定义支持字段并在属性 setter 中显式引发事件。
即使您不打算采用 Fody 路线,您仍然可以从 MVVM 属性定义中删除许多冗长的内容。
给定模型/视图模型的基类
/// <summary>
/// Base class that implements INotifyPropertyChanged
/// </summary>
public abstract class BindableBase: INotifyPropertyChanged
{
// INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// update a property value, and fire PropertyChanged event when the value is actually updated
protected bool Set<T>(string propertyName, ref T field, T newValue)
{
if (EqualityComparer<T>.Default.Equals(field, newValue))
return false;
field = newValue;
RaisePropertyChanged(propertyName);
return true;
}
// update a property value, and fire PropertyChanged event when the value is actually updated
// without having to pass in the property name
protected bool Set<T>(ref T field, T newValue, [CallerMemberName]string propertyName = null)
{
return Set(propertyName, ref field, newValue);
}
}
现在可以将属性定义编写为
public class Session: BindableBase
{
private string sessionName;
public string SessionName
{
get => sessionName;
private set => Set(ref sessionName, value);
}
}