为什么我的财产通知未触发?

时间:2019-01-26 23:24:58

标签: c# inotifypropertychanged

我有一个类的层次结构。相关位包括在下面。我期望通过WPF绑定更改FilterCritetionInteger.CriterionValue时,我会在FilterCriterionCollection中收到通知。但是,在调用FilterCriterionInteger.CriterionValue setter的同时,永远不会调用FilterCriterionCollection.Criterion_PropertyChanged方法。

很明显,我误解了某些东西,或者连接不正确。我只是找不到。为什么我的通知没有发生? (请让我知道是否在任何地方都需要更多上下文。)

ViewModelBase

public abstract class ViewModelBase : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;

  protected virtual void OnPropertyChanged(string propertyName)
  {
    PropertyChangedEventHandler pcHandler = this.PropertyChanged;

    if (pcHandler != null)
    {
      PropertyChangedEventArgs args = new PropertyChangedEventArgs(propertyName);
      pcHandler(this, args);
     }
  }  
}

FilterCriterionBase

public abstract class FilterCriterionBase : ViewModelBase
{
  public abstract bool IsValid { get; }
}

FilterCriterionInteger

public class FilterCriterionInteger : FilterCriterionBase
{
  private string _criterionValue = "0";
  public string CriterionValue
  {
    get { return _criterionValue; }
    set
    {
      _criterionValue = value;
      OnPropertyChanged("IsValid");
    }
  }

  public int? MaxValue { get; private set; } = null;

  public override bool IsValid
  {
    get
    {
      if (int.TryParse(_criterionValue, out int i))
      {
        if (MaxValue.HasValue && (i > MaxValue)) return false;
      }
      else
      {
        return false;
      }

      return true;
    }
  }
}

FilterCriterionCollection

public class FilterCriteriaCollection : ViewModelBase
{
  public FilterCriteriaCollection()
  {
    Criteria.CollectionChanged += Criteria_CollectionChanged;
  }

  ~FilterCriteriaCollection()
  {
    Criteria.CollectionChanged -= Criteria_CollectionChanged;
  }

  public ObservableCollection<FilterCriterionBase> Criteria { get; private set; } = new ObservableCollection<FilterCriterionBase>();

  private void Criteria_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
  {
    switch (e.Action)
    {
      case NotifyCollectionChangedAction.Add:
        foreach (FilterCriterionBase fb in e.NewItems)
        {
          fb.PropertyChanged += Criterion_PropertyChanged;
        }
        break;

      case NotifyCollectionChangedAction.Remove:
        foreach (FilterCriterionBase fb in e.NewItems)
        {
          fb.PropertyChanged -= Criterion_PropertyChanged;
        }
        break;
    }
  }

  private bool _isValid;
  public bool IsValid
  {
    get { return _isValid; }
    private set { _isValid = value; OnPropertyChanged("IsValid"); }
  }

  private void Criterion_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
  {
    using (FilterCriterionBase criterion = sender as FilterCriterionBase)
    {
      switch (e.PropertyName)
      {
        case "IsValid":
          {
            bool isvalid = true;

            foreach(FilterCriterionBase fcb in Criteria)
            {
              isvalid = fcb.IsValid;
              if (!isvalid) break;
            }

            IsValid = isvalid;
            break;
          }
      }
    }
  }
}

1 个答案:

答案 0 :(得分:1)

因此,事实证明,我是个白痴。上面的代码确实需要进行一些微调,但通常来说是合理的。我的主要问题是,在测试沙箱中,从测试一些JSON序列化/反序列化中获得了一些剩余代码。我意识到,经过反复的敲打,我正在发送反序列化的对象,这些对象丢失了事件通知上下文,因此不再处于循环中。

删除这篇文章会是适当的协议,因为除了仔细检查您的输入外,它实际上并不需要答案...?