I think "inheritance" is not the right term for you to be using in this context, though I don't know what is.
"Inheritance" implies a specific kind of relationship between classes and subclasses. You can build view model base classes and inherit from them, but you can't really meaningfully do that with views, because views are built through composition and not by implementing properties and methods.
It certainly can make sense to build a view model base class that does what you describe, though. I'm doing that right now in a project I'm working on. I have a view model class that supports links in a menu by exposing a CommandLinks
collection. Each CommandLink
object in the collection exposes link text, a more verbose description, and a Command
. In the view, I have have a DataTemplate
that lays out the Hyperlink
and TextBlock
inside a DockPanel
, and the DataTemplate
for the view model contains an ItemsControl
that's bound to the CommandLinks
collection in my view model. The view model subclasses populate their CommandLinks
collection, and Bob's your uncle. My application doesn't need to populate the CommandLinks
collection in the base class, because the commands are different for every view model class, but there's no reason that I couldn't.
I wouldn't call this "visual inheritance," though. Because if I decide that I want to lay out a specific view model class differently, I can't just override the DataTemplate
in my implementation of it. I have to build a new DataTemplate
specifically for that class. This is where the inheritance concept starts to break down.
If I set the DataContext
of a ContentPresenter
(say) to an instance of my view model, WPF will look through the resource dictionaries to find a DataTemplate
keyed by the object's type. It'll use the base type's template if the derived type doesn't have one defined. But if the derived type does have one defined, WPF will use that one instead. And you don't really have a way of inheriting one template from another, so the subclass's template can't just magically look like the base class's template.
You end up implementing it like this instead:
<DataTemplate DataType="{x:Type MyBaseClass}">
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type MyBaseClass}"> ...
<DataTemplate DataType="{x:Type MyDerivedClass1}"> ...
<DataTemplate DataType="{x:Type MyDerivedClass2}"> ...
</DataTemplate.Resources>
<DockPanel>
<ItemsControl DockPanel.Dock="Left" ItemsSource="{Binding CommandLinks}"/>
<ContentPresenter DataContext="{Binding}"/>
</DockPanel>
</DataTemplate>
This isn't truly inheritance. There's no way for someone to implement their own derived class without modifying the data template for the base class.
You can get around this, sort of, by giving the container template a key. But then the person implementing the view needs to know about this. He can't just do this, for instance:
<ItemsControl ItemsSource="{Binding MyObjectList}"/>
but instead has to do something like:
<ItemsControl ItemsSource="{Binding MyObjectList}" ItemTemplate="{StaticResource MyBaseClassTemplate}"/>
That doesn't seem like an enormous price to pay, to me. But then I'm usually the only developer on my projects.