首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >是否在属性值发生更改时引发事件?

是否在属性值发生更改时引发事件?
EN

Stack Overflow用户
提问于 2010-02-12 02:40:19
回答 6查看 187.6K关注 0票数 65

有一个属性,名为ImageFullPath1

代码语言:javascript
复制
public string ImageFullPath1 {get; set; }

每当事件的值发生变化时,我都会触发它。我意识到了INotifyPropertyChanged的变化,但我想通过事件来实现。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-02-12 02:47:51

INotifyPropertyChanged接口是使用事件的实现的。该接口只有一个成员PropertyChanged,这是一个消费者可以订阅的事件。

Richard发布的版本不安全。下面是如何安全地实现此接口:

代码语言:javascript
复制
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;
}

请注意,这将执行以下操作:

  • 抽象了属性更改通知方法,因此在condition).
  • Correctly尝试调用它之前,您可以轻松地将其应用于其他(尝试调用它之前) PropertyChanged委托的副本(如果不这样做,将创建一个竞争实现INotifyPropertyChanged接口。

如果要为正在更改的特定属性另外创建通知,可以添加以下代码:

代码语言:javascript
复制
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,它允许在源代码中摆脱属性名称的硬编码字符串:

代码语言:javascript
复制
    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();
            }
        }
    }
票数 161
EN

Stack Overflow用户

发布于 2010-02-12 04:44:18

我使用的模式基本上与as相同,但是如果您有很多属性,那么使用一点泛型方法魔术来使您的代码更具DRY可能会更好。

代码语言:javascript
复制
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方法设为虚拟方法,以允许子类覆盖它以捕获属性更改。

票数 36
EN

Stack Overflow用户

发布于 2010-02-12 02:45:02

在属性更改时引发事件正是INotifyPropertyChanged所做的事情。实现INotifyPropertyChanged需要一个成员,那就是PropertyChanged事件。您自己实现的任何东西都可能与该实现相同,因此不使用它没有任何好处。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2246777

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档