微软应该为INotifyPropertyChanged实现一些时髦的东西,就像在自动属性中,只需要指定{get;设置;通知;} 我认为这样做很有意义。或者做这个手术有什么并发症吗?
我们能在属性中实现类似notify的东西吗。在你的类中实现INotifyPropertyChanged是否有一个优雅的解决方案,或者唯一的方法是在每个属性中引发PropertyChanged事件。
如果不是,我们可以写一些东西来自动生成一段代码来引发PropertyChanged事件?
微软应该为INotifyPropertyChanged实现一些时髦的东西,就像在自动属性中,只需要指定{get;设置;通知;} 我认为这样做很有意义。或者做这个手术有什么并发症吗?
我们能在属性中实现类似notify的东西吗。在你的类中实现INotifyPropertyChanged是否有一个优雅的解决方案,或者唯一的方法是在每个属性中引发PropertyChanged事件。
如果不是,我们可以写一些东西来自动生成一段代码来引发PropertyChanged事件?
当前回答
虽然显然有很多方法可以做到这一点,但除了AOP的神奇答案之外,没有一种答案似乎是在没有本地字段可以引用的情况下,直接从视图模型设置Model的属性。
问题是不能引用属性。但是,您可以使用Action来设置该属性。
protected bool TrySetProperty<T>(Action<T> property, T newValue, T oldValue, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(oldValue, newValue))
{
return false;
}
property(newValue);
RaisePropertyChanged(propertyName);
return true;
}
这可以像下面的代码摘录一样使用。
public int Prop {
get => model.Prop;
set => TrySetProperty(x => model.Prop = x, value, model.Prop);
}
查看这个BitBucket repo,了解该方法的完整实现,以及实现相同结果的几种不同方法,包括使用LINQ的方法和使用反射的方法。请注意,这些方法的性能较慢。
其他回答
我认为人们应该多关注一下表现;当有很多对象需要绑定时(想想有10,000多行的网格),或者对象的值经常变化时(实时监控应用程序),它确实会影响UI。
我把这里和其他地方找到的各种实现进行了比较;查看INotifyPropertyChanged实现的性能比较。
下面是测试结果
这就是大规模的过度工程。这比仅仅以正确的方式进行要复杂得多,而且几乎没有任何好处。如果你的IDE支持代码片段(Visual Studio/MonoDevelop支持),那么你可以让这个实现变得非常简单。你需要输入的只是属性的类型和属性名。额外的三行代码将自动生成。
虽然显然有很多方法可以做到这一点,但除了AOP的神奇答案之外,没有一种答案似乎是在没有本地字段可以引用的情况下,直接从视图模型设置Model的属性。
问题是不能引用属性。但是,您可以使用Action来设置该属性。
protected bool TrySetProperty<T>(Action<T> property, T newValue, T oldValue, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(oldValue, newValue))
{
return false;
}
property(newValue);
RaisePropertyChanged(propertyName);
return true;
}
这可以像下面的代码摘录一样使用。
public int Prop {
get => model.Prop;
set => TrySetProperty(x => model.Prop = x, value, model.Prop);
}
查看这个BitBucket repo,了解该方法的完整实现,以及实现相同结果的几种不同方法,包括使用LINQ的方法和使用反射的方法。请注意,这些方法的性能较慢。
反射:利用反射的思想:
class ViewModelBase : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
bool Notify<T>(MethodBase mb, ref T oldValue, T newValue) {
// Get Name of Property
string name = mb.Name.Substring(4);
// Detect Change
bool changed = EqualityComparer<T>.Default.Equals(oldValue, newValue);
// Return if no change
if (!changed) return false;
// Update value
oldValue = newValue;
// Raise Event
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(name));
}//if
// Notify caller of change
return true;
}//method
string name;
public string Name {
get { return name; }
set {
Notify(MethodInfo.GetCurrentMethod(), ref this.name, value);
}
}//method
}//class
=>这里我的解决方案具有以下特征
public ResourceStatus Status
{
get { return _status; }
set
{
_status = value;
Notify(Npcea.Status,Npcea.Comments);
}
}
没有refelction 短的符号 业务代码中没有神奇的字符串 PropertyChangedEventArgs在应用程序中的可重用性 在一条语句中通知多个属性的可能性