tags:

views:

38

answers:

2

I have a collection that holds multiple types of items that all inherit from the same interface. This is bound to an ItemsControl. The DataContext of the window is set to the ViewModel that holds the collection.

What I would like to do is have each item of a different type in the collection use a different ViewModel.

So if my templates in the itemscontrol are setup like below I would like to have the first template have a DataContext of ViewModel1 and the second have a DataContext of ViewModel2. I can't set the DataContext directly on them because the ItemsControl will set the DataContext to the item.

Anyone know a solution to this, or a better way to do it using MVVM?

<DataTemplate DataType="{x:Type Models:ItemType1}">
    <Controls:MyControl Text="{Binding Body}"/>
</DataTemplate>

<DataTemplate DataType="{x:Type Models:ItemType2}">
    <Controls:MyControl2 Text="{Binding Body}"/>
</DataTemplate>
+4  A: 

Why don't you just expose a collection of ViewModels ?

var viewModels = new ObservableCollection<ViewModelBase>(items.Select(CreateViewModelFromItem));


private ViewModelBase CreateViewModelFromItem(Item item)
{
    if (item is ItemType1) return new ViewModel1((ItemType1)item);
    if (item is ItemType2) return new ViewModel2((ItemType2)item);
    ...
    throw new ArgumentException("Unknown model type");
}

And change your datatemplates to bind to the viewmodels, not the items...

Thomas Levesque
+1  A: 

Maybe you could use a ValueConverter that would generate the correct ViewModel :

<DataTemplate DataType="{x:Type Models:ItemType1}">
    <Controls:MyControl DataContext="{Binding Converter=ViewModelLocator}" Text="{Binding Body}"/>
</DataTemplate>

Not sure if it could possibly work but it's worth a try.

Serious