简体   繁体   中英

WPF/MVVM Load a View dynamically at runtime

I have a simple WPF application as below:

在此处输入图片说明

I also created 3 different views:

  • DetailType1.xaml
  • DetailType2.xaml
  • DetailType3.xaml

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.

  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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM