WPF MVVM: how to load on-demand views without using plug-in architecture?

I have Outlook, such as a WPF interface with navigation on the left, a toolbar at the top and a status bar at the bottom, all within the DockPanel .

The "main" application area is within the DataGrid , which is LastChild and therefore fills the remaining space, and currently it looks like this:

  <Grid DockPanel.Dock="Right"> <Grid.ColumnDefinitions> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> </Grid.RowDefinitions> <views:View1 Grid.Column="0" Grid.Row="0"/> <views:View2 Grid.Column="0" Grid.Row="0"/> <views:View3 Grid.Column="0" Grid.Row="0"/> <views:View4 Grid.Column="0" Grid.Row="0"/> </Grid> 

These views are all user controls that have their own ViewModels with the Visibility property bound to the property in its ViewModel and controlled by the selection of the navigation bar. When a navigation bar item is selected, the main ViewModel sends a message to ViewModels from the views and, after receiving the ViewModels message, sets its Visibility properties accordingly ...

Now this works fine, but does not seem to be correct, since all ViewModels of these views are created when the application starts, and not when the corresponding navigation bar is selected, raising questions about efficiency and memory usage ...

My question is, is there a way to load each view and its ViewModel β€œon demand” when the appropriate navigation bar is selected and unloads these views and ViewModels when another navigation bar is selected without resorting to PRISM / MEF or some other plugin architecture .. . and, more generally, how would you go about creating such an application with multiple views / ViewModels "embedded" in the main view?

+4
source share
1 answer

That's what I'm doing:

First, on the main ViewModel model (the one that serves the main window) add the Content property:

 object _content; public object Content { get { return _content; } set { _content = value; RaisePropertyChanged("Content"); } } 

When the user switches from view to view, set the Content property to the appropriate ViewModel for the selected view.

In the main window, you can display the current version of ContentModel using ContentControl:

 <ContentControl Content="{Binding Content}" /> 

... and somewhere above this, define a DataTemplate for each of the different ViewModels for which Content can be set:

 <DataTemplate DataType="{x:Type vm:FooViewModel}"> <my:FooUserControl /> </DataTemplate> <DataTemplate DataType="{x:Type vm:BarViewModel}"> <my:BarUserControl /> </DataTemplate> 

So now, ContentControl will be responsible for initializing and displaying each of your UserControls, depending on which ViewModel is currently "active".

+8
source

All Articles