Moh*_*yan 62 .net c# events properties
有一个属性,它名为ImageFullPath1
public string ImageFullPath1 {get; set; }
Run Code Online (Sandbox Code Playgroud)
每当它的值发生变化时,我都会开火.我知道要改变INotifyPropertyChanged,但我想用事件来做.
Aar*_*ght 151
该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;
}
Run Code Online (Sandbox Code Playgroud)
请注意,这会执行以下操作:
摘要属性更改通知方法,以便您可以轻松地将其应用于其他属性;
在尝试调用PropertyChanged委托之前制作委托的副本(未能执行此操作将创建竞争条件).
正确实现INotifyPropertyChanged界面.
如果要另外为要更改的特定属性创建通知,可以添加以下代码:
protected void OnImageFullPathChanged(EventArgs e)
{
EventHandler handler = ImageFullPathChanged;
if (handler != null)
handler(this, e);
}
public event EventHandler ImageFullPathChanged;
Run Code Online (Sandbox Code Playgroud)
然后在行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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Mik*_*erg 35
我使用与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
}
Run Code Online (Sandbox Code Playgroud)
通常我也会将OnPropertyChanged方法设置为virtual,以允许子类覆盖它以捕获属性更改.
在属性更改时引发事件正是INotifyPropertyChanged所做的事情.有一个必需的成员来实现INotifyPropertyChanged,那就是PropertyChanged事件.您自己实现的任何内容都可能与该实现相同,因此不使用它没有任何优势.
public event EventHandler ImageFullPath1Changed;
public string ImageFullPath1
{
get
{
// insert getter logic
}
set
{
// insert setter logic
// EDIT -- this example is not thread safe -- do not use in production code
if (ImageFullPath1Changed != null && value != _backingField)
ImageFullPath1Changed(this, new EventArgs(/*whatever*/);
}
}
Run Code Online (Sandbox Code Playgroud)
那就是说,我完全赞同瑞恩.这种情况正是INotifyPropertyChanged存在的原因.
| 归档时间: |
|
| 查看次数: |
161475 次 |
| 最近记录: |