3 回答
TA贡献1803条经验 获得超6个赞
该INotifyPropertyChanged接口是与事件实现。该界面只有一个成员,PropertyChanged这是消费者可以订阅的事件。
理查德发布的版本不安全。以下是安全实现此接口的方法:
public class MyClass : INotifyPropertyChanged
{
private string imageFullPath;
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, e);
}
protected void OnPropertyChanged(string propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
public string ImageFullPath
{
get { return imageFullPath; }
set
{
if (value != imageFullPath)
{
imageFullPath = value;
OnPropertyChanged("ImageFullPath");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
请注意,这将执行以下操作:
抽象属性更改通知方法,以便您可以轻松地将其应用于其他属性;
在尝试调用PropertyChanged代理之前,先制作该代理的副本(否则,将创建竞争条件)。
正确实现INotifyPropertyChanged接口。
如果要为更改的特定属性另外创建通知,则可以添加以下代码:
protected void OnImageFullPathChanged(EventArgs e)
{
EventHandler handler = ImageFullPathChanged;
if (handler != null)
handler(this, e);
}
public event EventHandler ImageFullPathChanged;
然后在该行OnImageFullPathChanged(EventArgs.Empty)之后添加该行OnPropertyChanged("ImageFullPath")。
由于我们有.Net 4.5,因此存在CallerMemberAttribute,它可以摆脱源代码中属性名称的硬编码字符串:
protected void OnPropertyChanged(
[System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
public string ImageFullPath
{
get { return imageFullPath; }
set
{
if (value != imageFullPath)
{
imageFullPath = value;
OnPropertyChanged();
}
}
}
TA贡献2041条经验 获得超4个赞
我使用与Aaronaught大致相同的模式,但是如果您有很多属性,最好使用一些通用方法魔术使代码更干燥。
public class TheClass : INotifyPropertyChanged {
private int _property1;
private string _property2;
private double _property3;
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) {
PropertyChangedEventHandler handler = PropertyChanged;
if(handler != null) {
handler(this, e);
}
}
protected void SetPropertyField<T>(string propertyName, ref T field, T newValue) {
if(!EqualityComparer<T>.Default.Equals(field, newValue)) {
field = newValue;
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
}
public int Property1 {
get { return _property1; }
set { SetPropertyField("Property1", ref _property1, value); }
}
public string Property2 {
get { return _property2; }
set { SetPropertyField("Property2", ref _property2, value); }
}
public double Property3 {
get { return _property3; }
set { SetPropertyField("Property3", ref _property3, value); }
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
通常,我还将OnPropertyChanged方法设为虚拟,以允许子类覆盖它以捕获属性更改。
TA贡献1802条经验 获得超5个赞
INotifyPropertyChanged正是在属性更改时引发事件。要实现INotifyPropertyChanged,需要一个成员,即PropertyChanged事件。您自己实现的任何内容都可能与该实现相同,因此不使用它没有任何好处。
- 3 回答
- 0 关注
- 674 浏览
添加回答
举报