2010-09-28 4 views
2

J'ai une collection qui contient plusieurs types d'éléments qui héritent tous de la même interface. Ceci est lié à un ItemsControl. Le DataContext de la fenêtre est défini sur le ViewModel qui contient la collection.WPF MVVM ItemsControl avec plusieurs ViewModels en fonction du type d'objet

Ce que je voudrais faire est que chaque élément d'un type différent de la collection utilise un ViewModel différent. Donc, si mes templates dans itemscontrol sont configurés comme ci-dessous, j'aimerais que le premier modèle ait un DataContext de ViewModel1 et le second un DataContext de ViewModel2. Je ne peux pas définir le DataContext directement sur eux parce que ItemsControl définira le DataContext à l'élément.

Quelqu'un sait-il une solution à cela, ou une meilleure façon de le faire en utilisant 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> 

Répondre

5

Pourquoi ne pas simplement exposer une collection de 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"); 
} 

Et changer vos DataTemplates pour se lier aux viewmodels, pas les articles ...

1

Peut-être que vous pourriez utiliser un ValueConverter qui générerait le correct ViewModel:

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

Je ne sais pas si cela pourrait fonctionner, mais ça vaut le coup d'essayer.