Adapts an ObservableCollection of a type for use as an ObservableCollection of a base type where covariance doesn’t work.
Sometimes it happens that you want to use a generic list with elements of a certain type as list with elements of a more general base type. After all you should be able to assign a
List<Button> instance to a
List<Control> field, right? For this purpose, .NET 4.0 supports so-called covariance that shall apply type inheritance to generic types. Unfortunately this only works in a few special cases so that you cannot rely on this feature in general. A detailed article by Marc Gravell explains the backgrounds of the topic.
That happened to me in a WPF MVVM project as I wanted to assign to a
ObservableCollection of general ViewModel instances a collection of specialised ViewModel instances and failed. For this purpose I then wrote this simple adapter. This class is derived from
ObservableCollection<BaseType> and adds a link to a
ObservableCollection<SubType> instance to that. It automatically synchronises both collections. That is possible because an ObservableCollection provides the required events for it. Whenever the collection on either side of the adapter is changed, the adapter will carry the change over to the other side, just as if it was the same collection instance.
The purpose and usage of this class are probably best explained with an example. Let us assume there is a tree view in a WPF View and it can contain diverse objects. A CodeProject article by Josh Smith explains how to use the WPF TreeView easily with a ViewModel. All objects are of the type
TreeItemViewModel which has, among several display states, a
Children property that contains the sub-elements of the node (
PersonViewModel be a type derived from TreeItemViewModel. It represents a person and is suited for use with TreeView items. In our application there is a property that contains all persons as a list of
If one tree node only contains persons, you might as well assign a collection of persons to its
Children property. But that fails due to incompatible generic types. Instead, you can now use this adapter:
// persons. Is is derived from TreeItemViewModel because it is a tree node itself.
class PersonListViewModel : TreeItemViewModel
// The LoadChildren method is called when the subnodes of a tree node are
protected override void LoadChildren()
// The Children property of TreeItemViewModel is of the type
// ObservableCollection<TreeItemViewModel> because it contains all
// subnodes and cannot set a more specific type.
new ObservableCollectionAdapter<TreeItemViewModel, PersonViewModel>(
As soon as the application changes the collection of persons in the project, like adding a new person, this change is automatically carried over to the
Children list and the new entry appears in the tree view. Just like you would expect it from WPF data binding.
To use the ObservableCollectionAdapter class, you also need the OpLock class.
ObservableCollectionAdapter.cs2.5 KiBQuelltext der ObservableCollectionAdapter-Klasse
Copying and distribution of this file, with or without modification, are permitted provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty. (GNU All-Permissive licence)
- Created on 2012-09-06.