我有一个类的层次结构。相关位包括在下面。我期望通过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;
}
}
}
}
}
答案 0 :(得分:1)
因此,事实证明,我是个白痴。上面的代码确实需要进行一些微调,但通常来说是合理的。我的主要问题是,在测试沙箱中,从测试一些JSON序列化/反序列化中获得了一些剩余代码。我意识到,经过反复的敲打,我正在发送反序列化的对象,这些对象丢失了事件通知上下文,因此不再处于循环中。
删除这篇文章会是适当的协议,因为除了仔细检查您的输入外,它实际上并不需要答案...?