【问题标题】:How to intercept NotifyPropertyChange event如何拦截 INotifyPropertyChanged 事件
【发布时间】:2011-04-10 08:50:46
【问题描述】:

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

DoStuff()

我不想在每次 property1、property2 或 property3 更改时触发此函数。 当然我可以把这个函数放在我班级的 set 块中,但这不是一个好主意(我认为)。

【问题讨论】:

  • 请在问题中指定您要过滤掉其他引发 NotifyPropertyChanged 事件的属性

标签: c# properties inotifypropertychanged intercept


【解决方案1】:

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

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
    }
}

【讨论】:

  • 您可能希望将您的活动更改为PropertyChanged += (sender, args) =&gt; if(args.PropertyName == "property1" || args.PropertyName == "property2" || args.PropertyName == "property3") DoStuff();
  • 嗯,如果我要调用的函数在其他类中怎么办?
  • @Berial,添加了示例用法来拦截来自不同类而不是提高PropertyChanged的类
  • @Scott Chamberlain,你说得对,我发布的示例没有过滤更改的属性:) 更新我的示例。
  • 我想这个“viewModel.PropertyChanged += (sender, args)”是某种 LINQ 代码。我对 LINQ 的了解不够好,无法理解这一点。你能用普通的c#写吗?对我来说会更清楚
【解决方案2】:

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

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

编辑

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

【讨论】:

  • 我需要在调用 NotifyPropertyChanged 时调用函数 - 但前提是 Property1、Property2 或 Property3 已更改
【解决方案3】:
【解决方案4】:

您可以从 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.
}

【讨论】:

    【解决方案5】:

    窃取以利沙的答案来回答你在梅林的回答中的问题

    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 在您的主代码中自行注册一个事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      • 2011-07-25
      • 1970-01-01
      • 1970-01-01
      • 2015-11-05
      • 2021-06-27
      相关资源
      最近更新 更多