DataTemplate-driven Vedi iniezione con MVVM
-
16-09-2019 - |
Domanda
Ho una visione contenitore che sembra qualcosa di simile
<UserControl x:Class="Views.ContainerView">
<UserControl.Resources>
<ResourceDictionary>
<DataTemplate DataType="{x:Type viewmodels:AViewModel}">
<views:MyView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:BViewModel}">
<views:MyView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:CViewModel}">
<views:MyView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:DViewModel}">
<views:MyView />
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<ListBox ItemsSource="{Binding Path=AvailableViewModels}"
SelectedItem="{Binding Path=CurrentViewModel}"
IsSynchronizedWithCurrentItem="True" />
<ContentControl Content="{Binding Path=CurrentViewModel}" />
</Grid>
</UserControl>
Tutti i miei ViewModels ereditano BaseViewModel così ho trasformato la mia vista in questo
<UserControl x:Class="Views.ContainerView">
<UserControl.Resources>
<ResourceDictionary>
<DataTemplate DataType="{x:Type viewmodels:BaseViewModel}">
<views:MyView />
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<StackPanel>
<ListBox ItemsSource="{Binding Path=AvailableViewModels}"
SelectedItem="{Binding Path=CurrentViewModel}"
IsSynchronizedWithCurrentItem="True" />
<ContentControl Content="{Binding Path=CurrentViewModel}" />
</StackPanel>
</UserControl>
pensando che sarebbe istanziare un solo MyView e basta associare nuovamente il ViewModel quando ListBox.SelectedItem cambia. Sto capendo questo comportamento correttamente? Si tratta di una pratica preferita? Come posso verificare che non sto a sfornare la memoria, come posso passare da una visualizzazione all'altra?
Soluzione
Sarà istanziare un nuovo MyView per ogni modello di vista che si usa. Se si desidera riutilizzare i controlli utente, è possibile impostare la proprietà DataContext su ogni controllo utente.
Altri suggerimenti
Per espandere sulla risposta di Pavel e chiarire che cosa accade quando i punti di vista quando si cambia view-modelli è che una nuova visione verrà generato per la nuova vista-modello e la vecchia vista sarà si spera essere garbage collection in tempo.
Il problema con questo è a volte avremo viste che registra a qualche evento in codice dietro (eventi non deboli) e questo impedisce la vista di essere raccolte e hanno perdite di memoria.
Due approcci.
- Qualsiasi sottoscrizione di eventi in vista di codice sottostante dovrebbe essere indebolire (EventAggregator in PRISM) per consentire la raccolta dei rifiuti.
- Pubblicare un esempio della vista con il contenitore unità e risolverlo quando è necessario riutilizzarlo. Prima di iniettare nella regione, solo aggiornare il DataContext.
Spero che questo aiuti.