Quan Nguyen
Quan Nguyen

Reputation: 582

WPF/MVVM Load a View dynamically at runtime

I have a simple WPF application as below:

enter image description here

I also created 3 different views:

and each view has it's own ViewModel

ParentView.xaml

...
<!-- Detail Area -->
<GroupBox x:Name="groupDetails" Grid.Column="0" Header="Details"
                      HorizontalAlignment="Stretch"
                      Grid.Row="0" VerticalAlignment="Stretch">
   <GroupBox.Resources>
        <ResourceDictionary>
             <DataTemplate DataType="{x:Type vm:DetailType1ViewModel}">
                  <views:DetailType1View/>
             </DataTemplate>
             <DataTemplate DataType="{x:Type vm:DetailType2ViewModel}">
                  <views:DetailType2View/>
             </DataTemplate>
        </ResourceDictionary>
   </GroupBox.Resources>
   <ContentPresenter DataContext="{Binding}" Content="{Binding Path=BaseTypeViewModel}" />
</GroupBox>
...

ParentViewModel.cs

...
public BaseViewModel BaseTypeViewModel
{
    get { return GetValue<BaseViewModel>(); }
    set
    {
        SetValue(value);
    }
}

private void ShowDetailDialog()
{
    var vm = GetViewModelByID(SelectedID);
    BaseTypeViewModel = vm;
}

private BaseViewModel GetViewModelByID(int Id)
{
    switch (Id)
    {
        case 1:
            return IoC.Get<DetailType1ViewModel>();
        case 2:
            return IoC.Get<DetailType2ViewModel>();
    }
}
...

DetailType1ViewModel.cs

public class DetailType1ViewModel : BaseViewModel
{
    ...
}

My question is:

Everytime I double-click row of DataGrid on the left pane, I want to load one of above views into Details area depend on the selected ID. So what are the techniques can be used? It would be nice if you can show me a code sample.

Thanks to all for the help.

Upvotes: 2

Views: 4913

Answers (1)

haindl
haindl

Reputation: 3221

  1. Create a <DataTemplate> within a <ResourceDictionary> for each ViewModel that you want to display in the detail area (with the correct DataType={x:Type local:DetailTypeViewModelX}).
  2. Ensure that this <ResourceDictionary> is merged into an ancestor of the details area. A possible place would be <Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="..." />.
  3. Bind the DataContext of the details area to the instance of the ViewModel you want to display.
  4. Create a <ContentPresenter Content="{Binding}" /> in the details area where you want to display the contents of the <DataTemplate> from step 1.

This should work and follow the overall concept of MVVM.

Upvotes: 3

Related Questions