正確更新IsAnythingSelected
,你必須處理兩個類型的通知:
- 通知有關
MyModel.Series
集合改變;
- 通知約
MyModel.Series
集合項目屬性發生變化。
第一個可以實現「開箱即用」與ObservableCollection<T>
(或任何其他集合,實現INotifyCollectionChanged
。
第二個需要一個定製的解決方案(至少,我不知道任何現有的「開箱即用」 一節)
你可以用項目屬性結合ObservableCollection<T>
改操作是這樣的:
class MyObservableCollection<T> : ObservableCollection<T>
where T : INotifyPropertyChanged
{
private void Initialize()
{
// initial PropertyChanged subscription
foreach (var item in Items)
{
SubscribeItemPropertyChanged(item);
}
}
private void SubscribeItemPropertyChanged(object item)
{
((INotifyPropertyChanged)item).PropertyChanged += HandleItemPropertyChanged;
}
private void UnSubscribeItemPropertyChanged(object item)
{
((INotifyPropertyChanged)item).PropertyChanged -= HandleItemPropertyChanged;
}
protected virtual void HandleItemPropertyChanged(object sender, PropertyChangedEventArgs args)
{
var handler = ItemPropertyChanged;
if (handler != null)
{
handler(sender, args);
}
}
protected override void ClearItems()
{
// we should unsubscribe from INotifyPropertyChanged.PropertyChanged event for each item
Items.ToList().ForEach(item => Remove(item));
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
base.OnCollectionChanged(e);
// subscribe for new items property changing;
// un-subscribe for old items property changing
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
SubscribeItemPropertyChanged(e.NewItems[0]);
break;
case NotifyCollectionChangedAction.Remove:
UnSubscribeItemPropertyChanged(e.OldItems[0]);
break;
case NotifyCollectionChangedAction.Replace:
SubscribeItemPropertyChanged(e.NewItems[0]);
UnSubscribeItemPropertyChanged(e.OldItems[0]);
break;
}
}
public MyObservableCollection()
: base()
{
}
public MyObservableCollection(IEnumerable<T> collection)
: base(collection)
{
Initialize();
}
public MyObservableCollection(List<T> list)
: base(list)
{
Initialize();
}
public EventHandler<PropertyChangedEventArgs> ItemPropertyChanged;
}
...,並MyModel.Series
一個MyObservableCollection<T>
實例。 然後,你的類,它包含IsAnythingSelected
,看起來就像這樣:
// somewhere in code, where `MyModel` being initialized:
MyModel.Series.CollectionChanged += (sender, args) => RaisePropertyChanged("IsAnythingSelected");
MyModel.Series.ItemPropertyChanged += (sender, args) => RaisePropertyChanged("IsAnythingSelected");
public bool IsAnythingSelected
{
get
{
return MyModel.Series.Any(p => p.IsSelected && p.GetType() == typeof(LineSeries));
}
}
你甚至不需要IsAnythingSelected
是在這種情況下,讀寫屬性。只需通知它已更改,並且綁定引擎將重新讀取其值。
你可以改變'MyModel'的實現嗎? – Dennis