I think something like this should work right out of the box:
<UserControl.Resources> <DataTemplate DataType="{x:Type vm:GenericQuestionViewModel}"> <v:GenericQuestion/> </DataTemplate> <DataTemplate DataType="{x:Type tvm:GeographyQuestionViewModel}"> <tv:GeographyQuestion/> </DataTemplate> <DataTemplate DataType="{x:Type tvm:BiologyQuestionViewModel}"> <tv:BiologyQuestion/> </DataTemplate> </UserControl.Resources> <ContentControl Content="{Binding QuestionViewModel}">
Edit:
Yes, this should definitely work. Here is a more complete example:
Basic view model
public class MainWindowViewModel : ViewModelBase { public ObservableCollection<QuestionViewModel> QuestionViewModels { get; set; } public MainWindowViewModel() { QuestionViewModels = new ObservableCollection<QuestionViewModel> { new GenericQuestionViewModel(), new GeographyQuestionViewModel(), new BiologyQuestionViewModel() }; } }
Question View Models
public abstract class QuestionViewModel : ViewModelBase { } public class GenericQuestionViewModel : QuestionViewModel { } public class GeographyQuestionViewModel : QuestionViewModel { } public class BiologyQuestionViewModel : QuestionViewModel { }
User controls
<UserControl x:Class="WpfApplication1.GenericQuestion" ...> <Grid> <TextBlock Text="Generic Question" /> </Grid> </UserControl> <UserControl x:Class="WpfApplication1.GeographyQuestion" ...> <Grid> <TextBlock Text="Geography Question" /> </Grid> </UserControl> <UserControl x:Class="WpfApplication1.BiologyQuestion" ...> <Grid> <TextBlock Text="Biology Question" /> </Grid> </UserControl>
Main window
<Window x:Class="WpfApplication1.MainWindow" ... Title="MainWindow" Height="900" Width="525"> <Window.DataContext> <local:MainWindowViewModel /> </Window.DataContext> <Window.Resources> <DataTemplate DataType="{x:Type local:GenericQuestionViewModel}"> <local:GenericQuestion /> </DataTemplate> <DataTemplate DataType="{x:Type local:GeographyQuestionViewModel}"> <local:GeographyQuestion /> </DataTemplate> <DataTemplate DataType="{x:Type local:BiologyQuestionViewModel}"> <local:BiologyQuestion /> </DataTemplate> </Window.Resources> <ItemsControl ItemsSource="{Binding QuestionViewModels}"> <ItemsControl.ItemTemplate> <DataTemplate> <ContentControl Content="{Binding}" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Window>
Update
Kyle Tolle noted a nice simplification for setting ItemsControl.ItemTemplate
. Here is the resulting code:
<ItemsControl ItemsSource="{Binding QuestionViewModels}" ItemTemplate="{Binding}" />
source share