What is the best way to switch views/usercontrols in MVVM-light and WPF?

前端 未结 1 1313
太阳男子
太阳男子 2020-12-02 13:28

I\'m relatively new to WPF and MVVM and the hardest thing I have found is how to simply switch a usercontrol or a view in an application.

In winforms, to have a cont

相关标签:
1条回答
  • 2020-12-02 14:19

    You would do so in your parent ViewModel.

    For example, if your page (call it PageViewModel) had two views (ViewModelA and ViewModelB), you would have a property on PageViewModel called CurrentView, and this would determine which View is visible. When PageViewModel.CurrentView is set to an instance of ViewModelA, then ViewA's DataTemplate is used to draw the content. When it's set to an instance of ViewModelB, ViewB's DataTemplate is displayed.

    <DataTemplate DataType="{x:Type local:PageViewModel}">
        <ContentControl Content="{Binding CurrentView}" />
    </DataTemplate>
    
    <DataTemplate DataType="{x:Type local:ViewModelA}">
        <TextBlock Text="I'm ViewModelA" />
    </DataTemplate>
    
    <DataTemplate DataType="{x:Type local:ViewModelB}">
        <TextBlock Text="I'm ViewModelB" />
    </DataTemplate>
    

    It would be ideal to call the switch views command from the parent view (in this case the DataTemplate for the PageViewModel), however if you wanted to switch views from within ViewModelA/B, you can either hook up the event manually when the objects get created (CurrentView.ChangeViewCommand = this.ChangeViewCommand) or look into a messaging system. MVVM Light has a simple Messenger class which I found was fairly easy to use, or Prism has a more advanced EventAggregator

    If you want to switch Views for the same ViewModel, I would recommend a Mode property that gets used to determine which view to use. For example:

    <DataTemplate x:Key="ViewA" DataType="{x:Type local:MyViewModel}">
        <TextBlock Text="I'm ViewModelA" />
    </DataTemplate>
    
    <DataTemplate x:Key="ViewB" DataType="{x:Type local:MyViewModel}">
        <TextBlock Text="I'm ViewModelB" />
    </DataTemplate>
    
    <DataTemplate DataType="{x:Type local:MyViewModel}">
        <ContentControl Content="{Binding }">
            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <Setter Property="ContentTemplate" Value="{StaticResource ViewA}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Mode}" Value="2">
                            <Setter Property="ContentTemplate" Value="{StaticResource ViewB}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </DataTemplate>
    

    EDIT

    I actually see this kind of question come up a lot, so posted something about it here if anyone is interested

    0 讨论(0)
提交回复
热议问题