将Eventhandler调用附加到Property

时间:2014-01-24 08:19:54

标签: c# events annotations

我有一个包含很多属性的简单POCO。为了简化事情,我们假设POCO看起来像这样:

public class Project
{
    public int ProjectId {get; set;}
}

现在我想创建一个在更改ProjectId时触发的事件。我现在拥有的是:

public class Project
{
    public int ProjectId {get; set;}

    public event EventHandler ProjectChanged;

    private void OnProjectChanged(EventArgs args)
    {
        if (ProjectChanged != null) ProjectChanged (this, args);
    }
}

现在我必须扩展Property以调用Eventhandler:

public class Project
{
    private int mProjectId;
    public int ProjectId
    {
        get { return this.mProjectId;}
        set
        {
            this.mProjectId = value;
            this.OnProjectChanged(EventArgs.Empty);
        }
    }

    public event EventHandler ProjectChanged;

    private void OnProjectChanged(EventArgs args)
    {
        if (ProjectChanged != null) ProjectChanged(this, args);
    }
}

我想知道是否有更简单的方法来附加Eventhandler。也许是某种注释?像

public class Project
{
    [OnChange("OnProjectChanged", EventArgs.Empty)]
    public int ProjectId {get; set;}

    public event EventHandler ProjectChanged;

    private void OnProjectChanged(EventArgs args)
    {
        if (ProjectChanged != null) ProjectChanged (this, args);
    }
}

1 个答案:

答案 0 :(得分:1)

从我在评论中发布的问题中获取一些想法,您可以实现一个实现INotifyPropertyChanged的抽象基类。每次声明属性时,都会调用SetField来触发PropertyChanged事件。

这避免了两件事:

1)每次使用抽象类

明确地实现INotifyProperty

2)每次显式实现一个触发事件的方法,将设置代码缩短为一行。

abstract class ModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

class Project : ModelBase
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set { SetField(ref _name, value, "Name"); }
    }
}

class TestRunner
{
    public TestRunner()
    {
        Project p = new Project();
        p.PropertyChanged += (o, e) =>
        {
            // Changed
        };
        p.Name = "Test";
    }
}