使用MVVM切换视图的最佳方法

时间:2018-06-21 15:49:58

标签: c# wpf xaml monogame

我正在开发一个使用与XAML和MVVM兼容的UI框架的游戏。我设法使我的框架连接起来,并且能够在视图之间切换。现在,我正在使用数据模板以及ContentControl来切换视图,我也在使用类似状态的模式来切换,并且我想知道这是否是一种好方法?我的视图有一个小问题,目前的设置方式是,我的MainWindow.xaml包含其他xaml文件的数据模板。问题在于视图只是被添加到MainWindow.xaml中,我想知道是否有一种方法可以隐藏以前的视图/内容,因此好像我在切换窗口/视图一样,而不仅仅是添加它们。这是说明我目前拥有的屏幕截图。Image of project。我的xaml文件非常简单,现在只包含一个按钮,这是我的xaml文件: `

MainWindow.xaml
<Grid
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:local="clr-namespace:PsalmsOfEia"
    xmlns:viewmodels="clr-namespace:PsalmsOfEia.UI.Menus.ViewModels"
    xmlns:views="clr-namespace:PsalmsOfEia.UI.Menus.Views">


    <Grid.DataContext>
        <viewmodels:MainViewModel />
    </Grid.DataContext>

        <Grid.Resources>
            <DataTemplate DataType="{x:Type viewmodels:LoginViewModel}">
                <views:LoginView/>
            </DataTemplate>
        </Grid.Resources>

         <DockPanel LastChildFill="True">
            <StackPanel>
            <ContentControl Content="{Binding SelectedViewModel}"/> 
            <Button Content="Login" Command="{Binding ChangeCommand}"/>
        </DockPanel>


   </Grid>

LoginView.xaml

   <UserControl x:Class="PsalmsOfEia.UI.Menus.Views.LoginView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:PsalmsOfEia"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800"
             xmlns:viewmodels="clr-namespace:PsalmsOfEia.UI.Menus.ViewModels"
             xmlns:views="clr-namespace:PsalmsOfEia.UI.Menus.Views">

        <UserControl.DataContext>
            <viewmodels:LoginViewModel />
        </UserControl.DataContext>

        <UserControl.Resources>
            <DataTemplate DataType="{x:Type viewmodels:CreateCharacterViewModel}">
                <views:CreateCharacterView/>
            </DataTemplate>
        </UserControl.Resources>
    <StackPanel>
        <ContentControl Content="{Binding SelectedViewModel}"/>
        <Button Content="Click Here" Command="{Binding LoginCommand}"/>

    </StackPanel>
</UserControl>

`

谁能告诉我是否有更好的方法来切换视图以及如何隐藏先前视图的内容(因为目前所有内容都已添加到主窗口中)。

谢谢

-乔什蒙德

2 个答案:

答案 0 :(得分:0)

不太确定您要寻找什么,但我使用了TabControl

<TabControl>
    <TabItem Header="Tab1">
        <local:UserControl1/>
    </TabItem>

    <TabItem Header="Tab2">
        <local:UserControl2/>
    </TabItem>

    <TabItem Header="Tab3">
        <local:UserControl3/>
    </TabItem>        
</TabControl>

我尝试将一个文件中的XAML数量减至最少,因此我创建了UserControl并将其添加到主视图中。

答案 1 :(得分:0)

我正在使用stackpanel和用户控件。

    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <StackPanel x:Name="myStackpanel1"  Grid.Row="0"  />
    <StackPanel x:Name="myStackpanel2"  Grid.Row="1"  />
    <Button x:Name="myButton" Width="200" Height="30" Grid.Row="2" Click="myButton_Click" Content="Click Me SP1" />
    <Button x:Name="myButton2" Width="200" Height="30" Grid.Row="3" Click="myButton2_Click" Content="Click Me2 SP2" />
</Grid>

代码

private int i,j = 0;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void myButton_Click(object sender, RoutedEventArgs e)
    {
        i++;
        if (i % 2 == 0)
        {
            myStackpanel1.Children.Clear();
            myStackpanel1.Children.Add(new UserControl1());
        }
        else
        {
            myStackpanel1.Children.Clear();
            myStackpanel1.Children.Add(new UserControl2());
        }

    }

    private void myButton2_Click(object sender, RoutedEventArgs e)
    {
        j++;
        if (j % 2 == 0)
        {
            myStackpanel2.Children.Clear();
            myStackpanel2.Children.Add(new UserControl2());
        }
        else
        {
            myStackpanel2.Children.Clear();
            myStackpanel2.Children.Add(new UserControl1());
        }
    }