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

时间:2014-03-06 08:20:10

标签: c# wpf properties inotifypropertychanged

我将属性绑定到WPF中的控件。属性值由while循环中的递归方法分配/更改。因此,值以~1 ms的速率分配。即使没有更改属性值,大多数时间值都不会更改,但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!");
         }
     }
}

我是否误解了“在财产价值发生变化时触发事件”或我的代码实施错误的想法?

2 个答案:

答案 0 :(得分:3)

我无法想象,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");
    }   
}

答案 1 :(得分:2)

是的,在你的第一个例子中,每当调用该属性setter时,它将执行其中的任何代码,包括OnPropertyChanged处理程序,不带偏见。在您的setter / getter中为属性提供适合的条件逻辑是完全有效的。这就是字段属性的美妙之处在于,您可以决定任何您喜欢的细节如何响应数据更改,无论是只读还是只写,无论您喜欢什么。

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