At class System.Windows.Controls.CollectionHelper the CanInsert IEnumerable extension methode you can change the following line:
-- return genericListType.GetGenericArguments()[0] == item.GetType();
to
++ return genericListType.GetGenericArguments()[0].IsAssignableFrom(item.GetType());
So it is possible to use a class hierachy as ItemsSource.
We had to override the CanAddItem methode of DragDropTarget/ItemsControlDragDropTarget and change behavior of CanInsert for our usage:
public class MyTreeViewDragDropTarget : TreeViewDragDropTarget
{
protected override bool CanAddItem(ItemsControl itemsControl, object data)
{
return (itemsControl.ItemsSource == null) || CanInsert(itemsControl.ItemsSource, data);
}
private static bool CanInsert(IEnumerable collection, object item)
{
ICollectionView collectionView = collection as ICollectionView;
if(collectionView != null)
{
return CanInsert(collectionView.SourceCollection, item);
}
if(collection.GetType().IsArray /*IReadOnlyCollection is not handled!*/)
{
return false;
}
Type genericListType =
collection.GetType()
.GetInterfaces()
.Where(interfaceType => interfaceType.FullName.StartsWith("System.Collections.Generic.IList`1", StringComparison.Ordinal))
.FirstOrDefault();
if(genericListType != null)
{
return genericListType.GetGenericArguments()[0].IsAssignableFrom(item.GetType());
}
return collection is IList;
}
}
-- return genericListType.GetGenericArguments()[0] == item.GetType();
to
++ return genericListType.GetGenericArguments()[0].IsAssignableFrom(item.GetType());
So it is possible to use a class hierachy as ItemsSource.
We had to override the CanAddItem methode of DragDropTarget/ItemsControlDragDropTarget and change behavior of CanInsert for our usage:
public class MyTreeViewDragDropTarget : TreeViewDragDropTarget
{
protected override bool CanAddItem(ItemsControl itemsControl, object data)
{
return (itemsControl.ItemsSource == null) || CanInsert(itemsControl.ItemsSource, data);
}
private static bool CanInsert(IEnumerable collection, object item)
{
ICollectionView collectionView = collection as ICollectionView;
if(collectionView != null)
{
return CanInsert(collectionView.SourceCollection, item);
}
if(collection.GetType().IsArray /*IReadOnlyCollection is not handled!*/)
{
return false;
}
Type genericListType =
collection.GetType()
.GetInterfaces()
.Where(interfaceType => interfaceType.FullName.StartsWith("System.Collections.Generic.IList`1", StringComparison.Ordinal))
.FirstOrDefault();
if(genericListType != null)
{
return genericListType.GetGenericArguments()[0].IsAssignableFrom(item.GetType());
}
return collection is IList;
}
}