我已经尝试查看与此相关的其他主题,但我还没有找到我的问题的有效实现。基本上,我有一个名为“FruitBasket”的 ObservableCollection,其中包含不同种类的水果。 FruitBasket 本身包含每种经过的水果类型的 ObservableCollections,以便它们可以用作 ListViews 的 ItemSources(用它们的名称表示) AppleContainer”和“OrangeContainer”),每个都显示一种水果。因为水果类本身实现了 INotifyPropertyChanged,所以修改它们的值会很好地触发 ListView 控件的更新,但是,FruitBasket 有一个从集合中所有其他水果的权重派生的“TotalWeight”属性。我希望“TotalWeight”更新 UI 中的 Label 控件,而无需刷新 UI。触发有关实际 ObservableCollection 本身(而不仅仅是其组成成员)的属性更改的通知更加困难,而且到目前为止我还没有找到任何有效的解决方案(或者我已经正确实现) .
public class FruitBasket : ObservableCollection<IFruit>
{
private decimal _totalWeight;
public FruitBasket()
{
this.Add(new OrangeContainer(this));
this.Add(new AppleContainer(this));
}
public OrangeContainer Oranges
{
get { return (OrangeContainer)this.Items[0]; }
}
public AppleContainer Apples
{
get { return (AppleContainer)this.Items[1]; }
}
public decimal TotalWeight
{
get { return _totalWeight; }
set { _totalWeight = value; }
}
internal void UpdateWeight(IFruit caller)
{
_totalWeight = 0;
foreach (Orange orng in (OrangeContainer)this.Items[0])
{
_totalWeight += orng.Weight;
}
foreach (Apple appl in (AppleContainer)this.Items[1])
{
_totalWeight += appl.Weight;
}
}
最佳答案
每当添加、删除项目或任何项目的 Weight 属性发生更改时,您都需要调用 FruitBasket 的 INotifyPropertyChanged.PropertyChanged 事件。
让我们将其分为两个任务:
- 添加、删除商品或更改商品重量时,应重新计算 TotalWeight。我们需要处理这些事件。
- 引发 FruitBasket.PropertyChanged 事件
为了遵循单一职责原则,我将这两个任务分为两个类:
1) - 这处理项目的 PropertyChanged 事件:
public abstract class ExtendedObservableCollection<T> : ObservableCollection<T> where T : INotifyPropertyChanged
{
protected override void ClearItems()
{
foreach (var item in Items) item.PropertyChanged -= ItemPropertyChanged;
base.ClearItems();
}
protected override void InsertItem(int index, T item)
{
item.PropertyChanged += ItemPropertyChanged;
base.InsertItem(index, item);
}
protected override void RemoveItem(int index)
{
this[index].PropertyChanged -= ItemPropertyChanged;
base.RemoveItem(index);
}
protected override void SetItem(int index, T item)
{
this[index].PropertyChanged -= ItemPropertyChanged;
item.PropertyChanged += ItemPropertyChanged;
base.SetItem(index, item);
}
abstract void ItemPropertyChanged(object sender, PropertyChangedEventArgs e);
}
2) - 必要时重新计算 TotalWeight
public class FruitBasket : ExtendedObservableCollection<IFruit>
{
protected override void ItemPropertyChanged(object sender, PropertyChangedEventArgs e){
UpdateWeight();
OnPropertyChanged("TotalWeight")
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
UpdateWeight();
OnPropertyChanged("TotalWeight")
base.OnCollectionChanged(e);
}
}
当然你的Fruit应该实现INotifyPropertyChanged接口(interface)。您会发现很多如何做到这一点的示例。非常简单。
关于c# - 在 ObservableCollection 上触发 InotifyPropertyChanged/CollectionChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30444874/