如何拦截NotifyPropertyChange事件

时间:2010-09-09 16:41:34

标签: c# properties inotifypropertychanged intercept

我刚刚发现了一个INotifyPropertyChange接口。我设法在我的clss中实现这个接口,一切正常。但是我想知道是否可以在代码中拦截此事件并触发一个函数 假设我有一个功能

DoStuff()
每次property1,property2或property3发生变化时,我都不会激活此函数。 当然我可以把这个函数放在我班上的set block中,但这不是一个好主意(我认为)。

5 个答案:

答案 0 :(得分:2)

如果您指的是处理此事件的内部方法,您可以通过在类构造函数中注册事件来实现。例如:

public class AnswerViewModel : IAnswerViewModel
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string content;

    public AnswerViewModel()
    {
        PropertyChanged += (sender, args) => DoStuff();
    }

    public string Content
    {
        get { return content; }
        set
        {
            content = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Content"));
        }
    }

    public void DoStuff()
    {
        // this method will be called whenever PropertyChanged event raised
    }
}

如果拦截方法属于其他类:

public class PropertiesInterceptor
{
    private readonly AnswerViewModel viewModel;

    private readonly List<string> propertiesToIntercept =
        new List<string> { "property1", "property2", "property3" };

    public PropertiesInterceptor(AnswerViewModel viewModel)
    {
        this.viewModel = viewModel;
        viewModel.PropertyChanged += OnPropertyChanged;
    }

    private void OnPropertyChanged(object sender, PropertyChangedEventArgs args)
    {
        if (propertiesToIntercept.Contains(args.PropertyName))
        {
            DoStuff();
        }
    }

    private void DoStuff()
    {
        // Do something with viewModel
    }
}

答案 1 :(得分:0)

您是否需要它来替换现有的NotifyPropertyChanged事件处理程序,或者只是在调用NotifyPropertyChanged时调用它?

如果你的意思是第二个,你可以简单地注册一个事件处理程序

修改

您可以添加一个在NotifyPropertyChanged上调用的事件处理程序,检查该属性参数是否等于Property1,Property2或Property3,然后才将它转发给您想要调用的实际函数。

答案 2 :(得分:0)

答案 3 :(得分:0)

您可以从RaisePropertyChanged()方法触发该方法:

public int Property1
{
    get { return this.property1; }
    set
    {
        if (this.property1 != value)
        {
            this.property1 = value;
            RaisePropertyChanged("Property1");
        }
    }
}

private void RaisePropertyChanged(string propertyName)
{
     if (PropertyChanged != null)
     {
         PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
     }

     DoStuff(); // Call DoStuff here.
}

答案 4 :(得分:0)

窃取Elisha的回答,在Merlyn的回答中回答你的问题

public class AnswerViewModel : IAnswerViewModel
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string property1;
    private string property2;
    private string propertyX;

    public AnswerViewModel()
    {
        PropertyChanged += (sender, args) => 
        {
            if(args.PropertyName == "Property1" || args.PropertyName == "Property2")
                DoStuff();
        }
    }

    public string Property1
    {
        get { return content; }
        set
        {
            property1 = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Property1"));
        }
    }
    public string Property2
    {
        get { return content; }
        set
        {
            property2 = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Property2"));
        }
    }
    public string PropertyX
    {
        get { return content; }
        set
        {
            propertyX = value;
            PropertyChanged(this, new PropertyChangedEventArgs("PropertyX"));
        }
    }

    public void DoStuff()
    {
        // this method will be called whenever PropertyChanged event raised from Property1 or Property2
    }
}

如果DoStuff类是成员,则可以

    private otherClass
    public AnswerViewModel()
    {
        PropertyChanged += (sender, args) => 
        {
            if(args.PropertyName == "Property1" || args.PropertyName == "Property2")
                otherClass.DoStuff();
        }
    }

否则你可以让otherClass在你的主代码中自己注册一个事件。