Un collaboratore e io abbiamo opinioni divergenti su quanto dovremmo aderire rigorosamente ai concetti MVVM. Cerco di seguirlo il più vicino possibile dove prende scorciatoie quasi tutte le possibilità che ottiene. Uno dei miei più grandi fastidi è quando ha punti di vista vincolanti per i modelli. La sua giustificazione è che un viewmodel sarebbe solo una reimplementazione del modello, ma con l'aggiunta della complessità di dover catturare e rilanciare gli eventi (la maggior parte dei nostri modelli e modelli di visualizzazione implementano entrambi INotifyPropertyChanged).
Ad esempio, in un caso, c'è TheViewModel che espone TheModel come una proprietà. Il datacontext di TheView è impostato su TheViewModel . TheView contiene un TreeView who's ItemSource è una raccolta su TheModel . Ogni elemento figlio in TreeView è un tipo di modello che contiene proprietà direttamente associate a TreeView.
Public Class TheViewModel
Public Property TheModel as ModelObjectA
End Class
Public Class ModelObjectA
Inherits ModelBase
Public Property ModelItems as ObservableCollection(Of ModelObjectB)
End Class
Public Class ModelObjectB
Inherits ModelBase
Public Property Items as ObservableCollection(Of ModelBase)
Public Property IsValid as Boolean
Public Property Is as Boolean
End Class
Public Class ModelBase
Public Property Name as String
Public Property Type as String
End Class
<UserControl x:Class="TheView" DataContext="{StaticResource TheViewModel}">
<TreeView x:Name="ModelTree" ItemsSource="{Binding Path=TheViewModel.ModelItems}" >
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding IsValid}" Value="False">
<Setter Property="Background" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding IsModified}" Value="True">
<Setter Property="Foreground" Value="Magenta" />
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<!--ModelObjectB-->
<HierarchicalDataTemplate DataType="{x:Type mdl:ModelObjectC}" ItemsSource="{Binding Items}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Type}" />
</StackPanel>
</HierarchicalDataTemplate>
<!--ModelObjectC-->
<HierarchicalDataTemplate DataType="{x:Type mdl:ModelObjectC}" ItemsSource="{Binding Items}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Type}" />
</StackPanel>
</HierarchicalDataTemplate>
<!--ModelObjectD-->
<HierarchicalDataTemplate DataType="{x:Type mdl:ModelObjectD}" ItemsSource="{Binding Items}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Type}" />
</StackPanel>
</HierarchicalDataTemplate>
<!--Model Base-->
<DataTemplate DataType="{x:Type mdl:ModelBase}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Type}" />
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
<ContentPresenter Content="{Binding Path=SelectedItem, ElementName=ModelTree, Converter={StaticResource ModelToViewModelConverter}}" />
</UserControl>
Nota: Questa è una versione semplificata del nostro vero programma, e potrei aver dimenticato alcuni dei dettagli banali (come UserControl che ha due elementi figlio e setter / getter di proprietà).
Non credo che quanto sopra sia corretto. Penso che le collezioni dovrebbero essere esposte alla vista come raccolte di viewmodels (piuttosto che collezioni di modelli). Soprattutto se si considera che ognuno dei modelli ha un modello di visualizzazione corrispondente e, alla fine, l'elemento selezionato viene trasformato in un modello di vista (tramite un convertitore).
Che cosa pensano tutti? Va bene avere la vista vincolante per i modelli in casi come questo, o le collezioni dovrebbero essere viewmodels? Ho bisogno di buoni argomenti per convincere il mio collega che dovrebbe essere cambiato, o per convincermi che l'attuale implementazione è l'approccio giusto.