I have a ViewModel defined like this:
public class LocationTreeViewModel :
ObservableCollection, INotifyPropertyChanged
I just implemented a workaround that is certainly less than perfect, and does require a bit of code in your ViewModel (which. because the VM shouldn't know about the view, breaks strict MVVM).
Define your generic type, and then define a class of that type with the lowest-common-ancestor as the type argument:
class GenericClass { }
class Class1 : GenericClass { }
class Class2 : GenericClass { }
class WorkaroundClass : GenericClass { }
In your viewmodel you'll need to declare your bound member as the ancestor type, and cast it.
// instead of:
// Apple DisplayFruit => GetGrannySmith();
Fruit DisplayFruit => (Fruit)GetGrannySmith();
In your xaml, you can then bind your data template to the ancestor class:
I'm pretty sure that because the Generic parent is, well, generic, you shouldn't run into any actual cases where the differences between your type arguments cause any problems.