When creating ViewModels in WPF it's sometimes necessary to transform data that is available in an ObservableCollection
(the source collection) into a collection of wrapper elements that extend/restrict/project the original elements (the target collection), while the number and order of the elements always mirror the original collection.
Just like the Select extension method, except that it is continuously updated and can therefore be used for WPF bindings.
If an element is added to the source at index x, the Wrapper of the same element is added at the same index x in the target collection. If the element at index y is removed in the source collection, the element at index y is removed in the target collection.
Say there is an ObservableCollection<ClassA>
, but what I need to bind to is an ReadOnlyObservableCollection<ClassB>
(or equivalent), where ClassB
-> ClassA
as follows:
class ClassB : INotifyPropertyChanged, IDisposable
{
public ClassB(ClassA a)
{
Wrapped = a;
(Wrapped as INotifyPropertyChanged).PropertyChanged+=WrappedChanged;
}
public ClassA Wrapped { get; private set; }
public int SomeOtherProperty { get { return SomeFunction(Wrapped); }
WrappedChanged(object s, NotifyPropertyChangedArgs a) { ... }
...
}
I can write my own TemplatedTransformCollectionWrapper
, where I can write this:
ObservableCollection<ClassA> source;
TemplatedTransformCollectionWrapper theCollectionThatWillBeUsedInABinding
= TemplatedTransformCollectionWrapper(source, classA => new ClassB(classA));
TemplatedTransformCollectionWrapper ideally wraps all collections that implement INotifyCollectionChanged
and correctly handles all possible add, remove, replace operations of the original, wrapped, collection.
It's not trivial to write TemplatedTransformCollectionWrapper
correctly and it seems to be the kind of thing that someone else has already done, maybe it's even part of the core framework. But I can't find it.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…