每次我编写MVVM应用程序(比如每4-6个月一次),我都会重写我的ViewModelBase类。这有很多原因,但假设我无法访问以前的代码,之前的代码是为客户端构建的,不是我的代码,或者我正在使用别人的机器,但仍然没有代码。
因此,我重写了基本的INotifyPropertyChanged实现,我认为每次都会有所不同。以下是我今天想出的:
public class ViewModelBase : INotifyPropertyChanged
{
protected void OnPropertyChanged<T>(Expression<Func<T>> expression)
{
var property = (MemberExpression)expression.Body;
this.OnPropertyChanged(property.Member.Name);
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}我希望得到一个简单而又小的好实现,以及对此的任何改进(在ViewModelBase中还需要哪些其他功能?)那就太好了。
发布于 2012-07-19 19:17:57
我已经用了一段时间了:
public abstract class PropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
var propertyChanged = this.PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected bool SetProperty<T>(ref T backingField, T Value, Expression<Func<T>> propertyExpression)
{
var changed = !EqualityComparer<T>.Default.Equals(backingField, Value);
if (changed)
{
backingField = Value;
this.RaisePropertyChanged(ExtractPropertyName(propertyExpression));
}
return changed;
}
private static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
{
var memberExp = propertyExpression.Body as MemberExpression;
if (memberExp == null)
{
throw new ArgumentException("Expression must be a MemberExpression.", "propertyExpression");
}
return memberExp.Member.Name;
}
}我可以这样写我的财产:
private int id;
public int Id
{
get
{
return this.id;
}
set
{
this.SetProperty(ref this.id, value, () => this.Id);
}
}发布于 2012-07-19 19:00:47
特别是与NotifyPropertyChanged相关的,我发现VerifyPropertyName是有用的。
来自乔希·史密斯的网站:实现INotifyPropertyChanged的基类
[Conditional("DEBUG"), DebuggerStepThrough()]
public void VerifyPropertyName(string propertyName)
{
// Verify that the property name matches a real,
// public, instance property on this object.
if (TypeDescriptor.GetProperties(this)(propertyName) == null) {
string msg = "Invalid property name: " + propertyName;
if (this.ThrowOnInvalidPropertyName) {
throw new Exception(msg);
} else {
Debug.Fail(msg);
}
}
}发布于 2016-03-03 18:11:04
这是很多年后的事了,但是现在任何一个偶然发现这件事的人都应该知道MVVM Light和PropertyChanged.Fody。
两者都在nuget.org上
https://codereview.stackexchange.com/questions/13823
复制相似问题