您可以使用下面的類:
public class BoundObservableCollection<T, TSource> : ObservableCollection<T>
{
private ObservableCollection<TSource> _source;
private Func<TSource, T> _converter;
private Func<T, TSource, bool> _isSameSource;
public BoundObservableCollection(
ObservableCollection<TSource> source,
Func<TSource, T> converter,
Func<T, TSource, bool> isSameSource)
: base()
{
_source = source;
_converter = converter;
_isSameSource = isSameSource;
// Copy items
AddItems(_source);
// Subscribe to the source's CollectionChanged event
_source.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_source_CollectionChanged);
}
private void AddItems(IEnumerable<TSource> items)
{
foreach (var sourceItem in items)
{
Add(_converter(sourceItem));
}
}
void _source_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
AddItems(e.NewItems.Cast<TSource>());
break;
case NotifyCollectionChangedAction.Move:
// Not sure what to do here...
break;
case NotifyCollectionChangedAction.Remove:
foreach (var sourceItem in e.OldItems.Cast<TSource>())
{
var toRemove = this.First(item => _isSameSource(item, sourceItem));
this.Remove(toRemove);
}
break;
case NotifyCollectionChangedAction.Replace:
for (int i = e.NewStartingIndex; i < e.NewItems.Count; i++)
{
this[i] = _converter((TSource)e.NewItems[i]);
}
break;
case NotifyCollectionChangedAction.Reset:
this.Clear();
this.AddItems(_source);
break;
default:
break;
}
}
}
如下使用它:
var models = new ObservableCollection<Model>();
var viewModels =
new BoundObservableCollection<ViewModel, Model>(
models,
m => new ViewModel(m), // creates a ViewModel from a Model
(vm, m) => vm.Model.Equals(m)); // checks if the ViewModel corresponds to the specified model
的BoundObservableCollection
將被更新時ObservableCollection
會改變,但周圍的其他方式(你會必須重寫幾個方法來做到這一點)
謝謝!我知道那裏有人已經完成了封裝這個功能的工作。一個問題:當更改操作是Remove時,我看到您使用isSameSource。爲什麼不只是使用e.OldStartingIndex和e.OldItems.Count: for(int i = 0; i
Eric
2010-05-18 15:47:44
@Eric,是的,它可以工作,而且它實際上會更好......如果您確定這兩個集合的順序相同。由於我不處理'NotifyCollectionChangedAction.Move'案件,這並不能保證...... – 2010-05-18 16:00:53
Ey謝謝。只是我在找什麼:) – 2011-09-25 10:05:29