在网上搜了一下切换用户控件的方法,发现几乎都没有使用MVVM思想,我在阅读 MaterialDesignToolkit 项目源码时,发现该项目采用了MVVM思想来切换界面,根据其代码,写了一个小Demo,实现了界面切换,大家可以参考一下。

使用Nuget命令安装MvvmLight包:
Install-Package MvvmLight -Version 5.4.1.1
建立Demo,效果如下图:
  • MainWindow.xaml代码,使用参数绑定,将要显示的界面集合绑定至ListBox的ItemsSource中,要显示的界面绑定至SelectedItem中,ContentControl控件用来显示用户界面,将用户控件绑定到ContentControl.Content属性上。
  •         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"
            xmlns:local="clr-namespace:ChangeFrm"
            xmlns:demo="clr-namespace:ChangeFrm.Model"
            DataContext="{Binding Main,Source={StaticResource Locator}}"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="4*"/>
            </Grid.ColumnDefinitions>
            <ListBox Grid.Column="0"  SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding ListDemo}">
                <ListBox.ItemTemplate>
                    <DataTemplate DataType="demo:DemoItemModel">
                        <TextBlock Text="{Binding NameStr}"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <ContentControl Grid.Column="1" Content="{Binding SelectedItem.ViewContent}"/>
        </Grid>
    </Window>
    
  • MainViewModel.代码
    进行参数的初始化,每个界面的初始化都在MainViewModel中进行,然后每个View和ViewModel的绑定也在MainViewModel中,这就实现了界面和代码的分离
  • using ChangeFrm.View;
    using GalaSoft.MvvmLight;
    using System.Collections.ObjectModel;
    namespace ChangeFrm.ViewModel
        public class MainViewModel : ViewModelBase
            /// <summary>
            /// Initializes a new instance of the MainViewModel class.
            /// </summary>
            public MainViewModel()
                MainInit();
            /// <summary>
            /// 初始化函数
            /// </summary>
            private void MainInit()
                ListDemo = new ObservableCollection<DemoItemModel>() {
                    new DemoItemModel()
                        NameStr = "第一个",
                        ViewContent= new FirstControl(){ DataContext =  new FirstViewModel()}
                    new DemoItemModel()
                        NameStr = "第二个",
                        ViewContent = new SecondControl(){ DataContext = new SecondViewModel()}
                    new DemoItemModel()
                        NameStr = "第三个",
                        ViewContent = new ThirdControl(){ DataContext = new ThirdViewModel()}
            private ObservableCollection<DemoItemModel> _ListDemo;
            /// <summary>
            /// 界面集合
            /// </summary>
            public ObservableCollection<DemoItemModel> ListDemo
                get { return _ListDemo; }
                set { _ListDemo = value; RaisePropertyChanged(() => ListDemo); }
            private DemoItemModel _SelectedItem;
            /// <summary>
            /// 选择的项
            /// </summary>
            public DemoItemModel SelectedItem
                get { return _SelectedItem; }
                set { _SelectedItem = value; RaisePropertyChanged(() => SelectedItem); }
    
  • DemoItemModel.cs代码
    主要存放每个界面的Content。
  • using GalaSoft.MvvmLight;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    namespace ChangeFrm.Model
        public class DemoItemModel:ViewModelBase
            private object _ViewContent;
            private string _NameStr;
            /// <summary>
            /// 名称
            /// </summary>
            public string NameStr
                get { return _NameStr; }
                set { _NameStr = value; RaisePropertyChanged(() => NameStr); }
            /// <summary>
            /// 内容
            /// </summary>
            public object ViewContent
                get { return _ViewContent; }
                set { _ViewContent = value; RaisePropertyChanged(() => ViewContent); }
    点击切换不同界面,效果如下

    使用MVVM思想实现了界面切换