繁体   English   中英

即使属性值未更改,也会触发 Propertychanged 事件

[英]Propertychanged event firing even when property value not changed

我将属性绑定到 WPF 中的控件。属性值通过 while 循环中的递归方法分配/更改。 因此,值的分配速率约为 1 毫秒。 大多数时间值根本不会更改,但即使属性值未更改,setter 中的 propertychanged 事件也会触发。 我在想,只有当一个字段的值要改变时,属性设置器才应该引发一个事件。 这是我的代码的简化版本:

public sealed class FX : System.ComponentModel.INotifyPropertyChanged 
{
   public event PropertyChangedEventHandler PropertyChanged;
   public void OnPropertyChanged(string PropertyName)
   {
      PropertyChangedEventHandler handler = PropertyChanged;
      if (handler != null)
      {
         handler(this, new PropertyChangedEventArgs(PropertyName));
      }
   }

   private bool _someBool1 = false;
   public bool SomeBool1
   {
       get { return _someBool1; }
       set
       {
          _someBool1 = value;
           OnPropertyChanged("SomeBool1");

           //MessageBox.Show("SomeBool1 : propertychanged event fired!");
       }
   }
}

根据http://www.codemag.com/Article/0907101 UI 是 PropertyChanged 事件的消费者。 虽然许多属性的值会不断地尽可能快地分配,但这可能会导致不必要的 UI 开销。 可以放置 OnPropertyChanged("SomeBool2"); 吗? 在 if 语句中? :

private bool _someBool2 = false;
public bool SomeBool2
{
    get { return _someBool2; }
    set
    {
         bool _someBool2OldValue = _someBool2;
         _someBool2 = value;

         if (_someBool2 != _someBool2OldValue)
         {
             OnPropertyChanged("SomeBool2");
             //MessageBox.Show("SomeBool2 : propertychanged event fired!");
         }
     }
}

我是否误解了“属性值更改时触发事件”的想法,或者我的代码实现有误?

我无法想象,带有someBool2OldValue东西打算用于什么:

set
{
     if (_someBool2 != value)
     {
         _someBool2 == value;
         OnPropertyChanged("SomeBool2");
     }
 }

此外,如果您正在运行某个循环,这会导致视图模型频繁更改属性,则完全停止触发PropertyChanged事件是有意义的:

protected bool StopFiringPropertyChanged { get; set; }

protected virtual void OnPropertyChanged(string propertyName)
{
    if (StopFiringPropertyChanged) 
    {
        return;
    }

    // fire event
}

并仅在完成所有属性的循环后才触发它,可以在循环期间更改它:

private void SomeMethodWithRecursiveLoop()
{
    StopFiringPropertyChanged = true;
    try
    {
         // do the work
    }
    finally
    {
        StopFiringPropertyChanged = false;
        OnPropertyChanged("SomeProperty1");
        OnPropertyChanged("SomeProperty2");
        OnPropertyChanged("SomeProperty3");
    }   
}

是的,在您的第一个示例中,每当调用该属性设置器时,它将不带偏见地执行其中的任何代码,包括您的OnPropertyChanged处理程序。 在属性的设置器/获取器中使用适合您的条件逻辑是完全有效的。 这就是字段上的属性之美,因为您可以决定喜欢的任何细节,无论该值是只读还是只写,只要您喜欢,该值如何响应数据更改。

对于第二个示例,您可以只使用'value'关键字而不是创建特定字段。

使用 CommunityToolkit 现在将为您提供一个自动执行此操作的方法: SetProperty(ref property, value)

只有当值不同时,这才会通知属性更改事件。

这是官方文档的链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM