有一个属性,名为ImageFullPath1
public string ImageFullPath1 {get; set; }
每当事件的值发生变化时,我都会触发它。我意识到了INotifyPropertyChanged
的变化,但我想通过事件来实现。
发布于 2010-02-12 02:47:51
INotifyPropertyChanged
接口是使用事件的实现的。该接口只有一个成员PropertyChanged
,这是一个消费者可以订阅的事件。
Richard发布的版本不安全。下面是如何安全地实现此接口:
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;
然后在OnPropertyChanged("ImageFullPath")
行之后添加OnImageFullPathChanged(EventArgs.Empty)
行。
因为我们有.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();
}
}
}
发布于 2010-02-12 04:44:18
我使用的模式基本上与as相同,但是如果您有很多属性,那么使用一点泛型方法魔术来使您的代码更具DRY可能会更好。
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方法设为虚拟方法,以允许子类覆盖它以捕获属性更改。
发布于 2010-02-12 02:45:02
在属性更改时引发事件正是INotifyPropertyChanged所做的事情。实现INotifyPropertyChanged需要一个成员,那就是PropertyChanged事件。您自己实现的任何东西都可能与该实现相同,因此不使用它没有任何好处。
https://stackoverflow.com/questions/2246777
复制相似问题