如何在C#6.0中实现INotifyPropertyChanged?
这个问题的答案已被编辑,说在C#6.0中,可以使用以下OnPropertyChanged过程实现INotifyPropertyChanged:
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
但是,从该答案中不清楚相应的属性定义应该是什么。 使用此构造时,在C#6.0中完整实现INotifyPropertyChanged是什么样的?
在合并各种更改后,代码将如下所示。 我用评论突出显示了改变的部分以及每个部分的帮助
public class Data : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { //C# 6 null-safe operator. No need to check for event listeners //If there are no listeners, this will be a noop PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } // C# 5 - CallMemberName means we don't need to pass the property's name protected bool SetField(ref T field, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer .Default.Equals(field, value)) return false; field = value; OnPropertyChanged(propertyName); return true; } private string name; public string Name { get { return name; } //C# 5 no need to pass the property name anymore set { SetField(ref name, value); } } }
我在我的项目中使用相同的逻辑。 我的应用程序中的所有视图模型都有一个基类:
using System.ComponentModel; using System.Runtime.CompilerServices; public class PropertyChangedBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
每个视图模型都inheritance自此类。 现在,在每个属性的setter中我只需要调用OnPropertyChanged()
。
public class EveryViewModel : PropertyChangedBase { private bool initialized; public bool Initialized { get { return initialized; } set { if (initialized != value) { initialized = value; OnPropertyChanged(); } } }
它为什么有效?
[CallerMemberName]
由编译器自动填充,并调用此函数的成员名称。 当我们从Initialized
调用nameof(Initialized)
,编译器将nameof(Initialized)
作为参数放入nameof(Initialized)
要记住的另一个重要细节
该框架要求PropertyChanged
和您绑定的所有属性都是public
。
我知道这个问题很老,但这是我的实施
Bindable使用字典作为属性存储。 为子类添加必要的重载以使用ref参数管理自己的后备字段非常容易。
代码:
public class Bindable : INotifyPropertyChanged { private Dictionary _properties = new Dictionary(); /// /// Gets the value of a property /// /// /// protected T Get([CallerMemberName] string name = null) { object value = null; if (_properties.TryGetValue(name, out value)) return value == null ? default(T) : (T)value; return default(T); } /// /// Sets the value of a property /// /// /// /// protected void Set (T value, [CallerMemberName] string name = null) { if (Equals(value, Get (name))) return; _properties[name] = value; OnPropertyChanged(name); } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
像这样使用
上述就是C#学习教程:如何在C#6.0中实现INotifyPropertyChanged?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
public class Item : Bindable { public Guid Id { get { return Get(); } set { Set (value); } } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1019065.html