zoukankan      html  css  js  c++  java
  • WPF MVVM 入门示例讲解

    M-V-VM是Model-View-ViewModel的简写,Model,ViewModel是个类文件(.cs文件),View是前台文件(,xaml文件)。假设我们的工程只有一个前台文件和一个后台文件,当设计要求越来越多的时候,前后台文件可能会高达上千行,甚至上万行,此时要想找到对应的代码,鼠标滚轮会滑的头大。学习MVVM便于工程调试,修改,移植。用MVVM如果只是修改或者更好显示界面,后台文件只需稍微的改动甚至不用改动。下面这个例子是V-VM模式就是view和viewmodel,先以简单的入门,工程集如下:

    <Window x:Class="Students.View"
    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:Students"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
    <Grid>

    <Grid.RowDefinitions>
    <RowDefinition Height="30"/>
    <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid x:Name ="StudetGrid" Grid.Row ="0">
    <Grid.DataContext>
    <!--声明创建一个ViewModel的实例,这个声明确定了ViewModel.cs是VM,这个声明建立了View.xaml与ViemModel之间的桥梁,这个myGrid所有绑定的属性(Name,Age,Sex)都值的是ViewModel.cs类中的成员-->
    <local:StudetViewModel/>
    </Grid.DataContext>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <TextBlock Text="姓名:" Grid.Column="0" HorizontalAlignment="Right"/>
    <TextBlock Text="{Binding Name}" Grid.Column="1"/>
    <TextBlock Text="年龄:" Grid.Column="2" HorizontalAlignment="Right" />
    <TextBlock Text="{Binding Age}" Grid.Column="3" />
    <TextBlock Text="性别:" Grid.Column="4" HorizontalAlignment="Right" />
    <TextBlock Text="{Binding Sex}" Grid.Column="5"/>
    <Button Content="更新" Grid.Column="6" Click="BtnClick" />

    </Grid>
    </Grid>
    </Window>

    View.xaml


    复制代码
    <Window x:Class="Students.View"
            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:Students"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
    
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid x:Name ="StudetGrid"  Grid.Row ="0">
                <Grid.DataContext>
                    <!--声明创建一个ViewModel的实例,这个声明确定了ViewModel.cs是VM,这个声明建立了View.xaml与ViemModel之间的桥梁,这个myGrid所有绑定的属性(Name,Age,Sex)都值的是ViewModel.cs类中的成员-->
                    <local:StudetViewModel/>
                </Grid.DataContext>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
    
                <TextBlock Text="姓名:" Grid.Column="0" HorizontalAlignment="Right"/>
                <TextBlock Text="{Binding Name}" Grid.Column="1"/>
                <TextBlock Text="年龄:" Grid.Column="2" HorizontalAlignment="Right"  />
                <TextBlock Text="{Binding Age}" Grid.Column="3" />
                <TextBlock Text="性别:" Grid.Column="4" HorizontalAlignment="Right" />
                <TextBlock Text="{Binding Sex}" Grid.Column="5"/>
                <Button Content="更新" Grid.Column="6" Click="BtnClick" />
    
            </Grid>
        </Grid>
    </Window>
    复制代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    namespace Students
    {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class View : Window
    {
    public static StudetViewModel viewModel;//声明一个类,但是没有实例化,把这个viewModel设为static方便其他页面文件互相访问绑定的属性
    public View()
    {
    InitializeComponent();
    viewModel = StudetGrid.DataContext as StudetViewModel;//在构造方法中实例化viewModel,这个viewModel就是View.xaml中声明的那个ViewModel实例,就是那个桥梁。
    }

    private void BtnClick(object sender, RoutedEventArgs e)
    {
    viewModel.Name = "小明";
    viewModel.Age = "15";
    viewModel.Sex = "男";
    }
    }
    }

    View.xaml.cs


    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace Students
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class View : Window
        {
            public static StudetViewModel viewModel;//声明一个类,但是没有实例化,把这个viewModel设为static方便其他页面文件互相访问绑定的属性
            public View()
            {
                InitializeComponent();
                viewModel = StudetGrid.DataContext as StudetViewModel;//在构造方法中实例化viewModel,这个viewModel就是View.xaml中声明的那个ViewModel实例,就是那个桥梁。
            }
    
            private void BtnClick(object sender, RoutedEventArgs e)
            {
                viewModel.Name = "小明";
                viewModel.Age = "15";
                viewModel.Sex = "男";
            }
        }
    }
    复制代码

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;

    namespace Students
    {
    public class StudetViewModel : INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
    if (PropertyChanged != null)
    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private string name;
    public String Name
    {
    get { return name; }
    set { name = value; OnPropertyChanged("Name"); }
    }

    private string age;
    public String Age
    {
    get { return age; }
    set { age = value; OnPropertyChanged("Age"); }
    }

    private string sex;
    public String Sex
    {
    get { return sex; }
    set { sex = value; OnPropertyChanged("Sex"); }
    }
    }
    }

    StudetViewModel.cs


    复制代码
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;
    
    namespace Students
    {
        public class StudetViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private string name;
            public String Name
            {
                get { return name; }
                set { name = value; OnPropertyChanged("Name"); }
            }
    
            private string age;
            public String Age
            {
                get { return age; }
                set { age = value; OnPropertyChanged("Age"); }
            }
    
            private string sex;
            public String Sex
            {
                get { return sex; }
                set { sex = value; OnPropertyChanged("Sex"); }
            }
        }
    }
    复制代码

    View.xaml是View,那如何确定StudetViewModel.cs就是VM呢?在View.xaml文件中有如下声明

     在前台文件中声明数据上下文指定类,指定的那个类就是ViewModel。先看一下运行效果吧

     这个工程文件里的StudetViewModel.cs其实就是Model和ViewModel合在一起了

     增加完Model类后的程序集如下:

     如何确定PeronModel就Model呢?因为它在ViewModel中有实例化

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;

    namespace Students
    {
    public class StudetViewModel : INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
    if (PropertyChanged != null)
    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }


    private PersonModel _studentModel = new PersonModel();//实例化Model中的类
    public PersonModel StudentModel
    {
    get { return _studentModel; }
    set { _studentModel = value; OnPropertyChanged("StudentModel"); }
    }
    }
    }

    StudetViewModel


    复制代码
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;
    
    namespace Students
    {
        public class StudetViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
    
            private PersonModel _studentModel = new PersonModel();//实例化Model中的类
            public PersonModel StudentModel
            {
                get { return _studentModel; }
                set { _studentModel = value; OnPropertyChanged("StudentModel"); }
            }
        }
    }
    复制代码

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;

    namespace Students
    {
    public class PersonModel : INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
    if (PropertyChanged != null)
    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private string name;
    public String Name
    {
    get { return name; }
    set { name = value; OnPropertyChanged("Name"); }
    }

    private string age;
    public String Age
    {
    get { return age; }
    set { age = value; OnPropertyChanged("Age"); }
    }

    private string sex;
    public String Sex
    {
    get { return sex; }
    set { sex = value; OnPropertyChanged("Sex"); }
    }
    }
    }

    Students


    复制代码
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;
    
    namespace Students
    {
        public class PersonModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private string name;
            public String Name
            {
                get { return name; }
                set { name = value; OnPropertyChanged("Name"); }
            }
    
            private string age;
            public String Age
            {
                get { return age; }
                set { age = value; OnPropertyChanged("Age"); }
            }
    
            private string sex;
            public String Sex
            {
                get { return sex; }
                set { sex = value; OnPropertyChanged("Sex"); }
            }
        }
    }
    复制代码

    <Window x:Class="Students.View"
    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:Students"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
    <Grid>

    <Grid.RowDefinitions>
    <RowDefinition Height="30"/>
    <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid x:Name ="StudetGrid" Grid.Row ="0">
    <Grid.DataContext>
    <!--声明创建一个ViewModel的实例,这个声明确定了ViewModel.cs是VM,这个声明建立了View.xaml与ViemModel之间的桥梁,这个myGrid所有绑定的属性(Name,Age,Sex)都值的是ViewModel.cs类中的成员-->
    <local:StudetViewModel/>
    </Grid.DataContext>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <TextBlock Text="姓名:" Grid.Column="0" HorizontalAlignment="Right"/>
    <TextBlock Text="{Binding StudentModel.Name}" Grid.Column="1"/>
    <TextBlock Text="年龄:" Grid.Column="2" HorizontalAlignment="Right" />
    <TextBlock Text="{Binding StudentModel.Age}" Grid.Column="3" />
    <TextBlock Text="性别:" Grid.Column="4" HorizontalAlignment="Right" />
    <TextBlock Text="{Binding StudentModel.Sex}" Grid.Column="5"/>
    <Button Content="更新" Grid.Column="6" Click="BtnClick" />

    </Grid>
    </Grid>
    </Window>

    View


    复制代码
    <Window x:Class="Students.View"
            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:Students"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
    
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid x:Name ="StudetGrid"  Grid.Row ="0">
                <Grid.DataContext>
                    <!--声明创建一个ViewModel的实例,这个声明确定了ViewModel.cs是VM,这个声明建立了View.xaml与ViemModel之间的桥梁,这个myGrid所有绑定的属性(Name,Age,Sex)都值的是ViewModel.cs类中的成员-->
                    <local:StudetViewModel/>
                </Grid.DataContext>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
    
                <TextBlock Text="姓名:" Grid.Column="0" HorizontalAlignment="Right"/>
                <TextBlock Text="{Binding StudentModel.Name}" Grid.Column="1"/>
                <TextBlock Text="年龄:" Grid.Column="2" HorizontalAlignment="Right"  />
                <TextBlock Text="{Binding StudentModel.Age}" Grid.Column="3" />
                <TextBlock Text="性别:" Grid.Column="4" HorizontalAlignment="Right" />
                <TextBlock Text="{Binding StudentModel.Sex}" Grid.Column="5"/>
                <Button Content="更新" Grid.Column="6" Click="BtnClick" />
    
            </Grid>
        </Grid>
    </Window>
    复制代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    namespace Students
    {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class View : Window
    {
    public static StudetViewModel viewModel;//声明一个类,但是没有实例化,把这个viewModel设为static方便其他页面文件互相访问绑定的属性
    public View()
    {
    InitializeComponent();
    viewModel = StudetGrid.DataContext as StudetViewModel;//在构造方法中实例化viewModel,这个viewModel就是View.xaml中声明的那个ViewModel实例,就是那个桥梁。
    }

    private void BtnClick(object sender, RoutedEventArgs e)
    {
    viewModel.StudentModel.Name = "小明";
    viewModel.StudentModel.Age = "15";
    viewModel.StudentModel.Sex = "男";
    }
    }
    }

    View.xaml.cs


    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace Students
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class View : Window
        {
            public static StudetViewModel viewModel;//声明一个类,但是没有实例化,把这个viewModel设为static方便其他页面文件互相访问绑定的属性
            public View()
            {
                InitializeComponent();
                viewModel = StudetGrid.DataContext as StudetViewModel;//在构造方法中实例化viewModel,这个viewModel就是View.xaml中声明的那个ViewModel实例,就是那个桥梁。
            }
    
            private void BtnClick(object sender, RoutedEventArgs e)
            {
                viewModel.StudentModel.Name = "小明";
                viewModel.StudentModel.Age = "15";
                viewModel.StudentModel.Sex = "男";
            }
        }
    }
    复制代码

    View中实例化过ViewModel,而ViewModel中实例化过Model,所以说ViewModel建立起了View与Model之间沟通的桥梁。一个ViewModel类中可以有多个不同的Model类的实例,比如我们还可以创建一个成绩类(Model),然后在ViewModel中去实例化,最后在View界面中去绑定各科成绩,这个好理解。

    View中也可以实例化多个ViewModel

    程序集如下:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;

    namespace Students
    {
    public class TeacherViewModel : INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
    if (PropertyChanged != null)
    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }


    private PersonModel _teacherModel = new PersonModel();//实例化Model中的类
    public PersonModel TeacherModel
    {
    get { return _teacherModel; }
    set { _teacherModel = value; OnPropertyChanged("TeacherModel"); }
    }
    }
    }

    TeacherViewModel


    复制代码
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;
    
    namespace Students
    {
        public class TeacherViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
    
            private PersonModel _teacherModel = new PersonModel();//实例化Model中的类
            public PersonModel TeacherModel
            {
                get { return _teacherModel; }
                set { _teacherModel = value; OnPropertyChanged("TeacherModel"); }
            }
        }
    }
    复制代码

    <Window x:Class="Students.View"
    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:Students"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
    <Grid>

    <Grid.RowDefinitions>
    <RowDefinition Height="30"/>
    <RowDefinition Height="30"/>
    <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid x:Name ="StudetGrid" Grid.Row ="0">
    <Grid.DataContext>
    <!--声明创建一个ViewModel的实例,这个声明确定了ViewModel.cs是VM,这个声明建立了View.xaml与ViemModel之间的桥梁,这个myGrid所有绑定的属性(Name,Age,Sex)都值的是ViewModel.cs类中的成员-->
    <local:StudetViewModel/>
    </Grid.DataContext>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <TextBlock Text="学生姓名:" Grid.Column="0" HorizontalAlignment="Right"/>
    <TextBlock Text="{Binding StudentModel.Name}" Grid.Column="1"/>
    <TextBlock Text="年龄:" Grid.Column="2" HorizontalAlignment="Right" />
    <TextBlock Text="{Binding StudentModel.Age}" Grid.Column="3" />
    <TextBlock Text="性别:" Grid.Column="4" HorizontalAlignment="Right" />
    <TextBlock Text="{Binding StudentModel.Sex}" Grid.Column="5"/>
    <Button Content="更新" Grid.Column="6" Click="BtnClick" />

    </Grid>
    <Grid x:Name ="TeacherGrid" Grid.Row ="1">
    <Grid.DataContext>
    <!--声明创建一个ViewModel的实例,这个声明确定了ViewModel.cs是VM,这个声明建立了View.xaml与ViemModel之间的桥梁,这个myGrid所有绑定的属性(Name,Age,Sex)都值的是ViewModel.cs类中的成员-->
    <local:TeacherViewModel/>
    </Grid.DataContext>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <TextBlock Text="老师姓名:" Grid.Column="0" HorizontalAlignment="Right"/>
    <TextBlock Text="{Binding TeacherModel.Name}" Grid.Column="1"/>
    <TextBlock Text="年龄:" Grid.Column="2" HorizontalAlignment="Right" />
    <TextBlock Text="{Binding TeacherModel.Age}" Grid.Column="3" />
    <TextBlock Text="性别:" Grid.Column="4" HorizontalAlignment="Right" />
    <TextBlock Text="{Binding TeacherModel.Sex}" Grid.Column="5"/>
    <Button Content="更新" Grid.Column="6" Click="BtnClickTeacher" />

    </Grid>
    </Grid>
    </Window>

    View.xaml

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    namespace Students
    {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class View : Window
    {
    public static StudetViewModel studentViewModel;//声明一个类,但是没有实例化,把这个viewModel设为static方便其他页面文件互相访问绑定的属性
    public static TeacherViewModel teacherViewModel;
    public View()
    {
    InitializeComponent();
    studentViewModel = StudetGrid.DataContext as StudetViewModel;//在构造方法中实例化viewModel,这个viewModel就是View.xaml中声明的那个ViewModel实例,就是那个桥梁。
    teacherViewModel = TeacherGrid.DataContext as TeacherViewModel;
    }

    private void BtnClick(object sender, RoutedEventArgs e)
    {
    studentViewModel.StudentModel.Name = "小明";
    studentViewModel.StudentModel.Age = "15";
    studentViewModel.StudentModel.Sex = "男";
    }

    private void BtnClickTeacher(object sender, RoutedEventArgs e)
    {
    teacherViewModel.TeacherModel.Name = "王老师";
    teacherViewModel.TeacherModel.Age = "30";
    teacherViewModel.TeacherModel.Sex = "女";
    }
    }
    }

    View.xaml.cs

    效果如下:

     上面的示例中,控件的成员属性和View分开了,但是按键的Click事件内容还是在后台文件实现的,那怎么把事件属性也和View分开呢?

    <Button Content="更新" Grid.Column="6" Command="{Binding CommadUpdata}" />
    <Button Content="更新" Grid.Column="6" Command="{Binding CommadUpdata}" />

    把Button 的Click用Commad代替,以TeacherViewModel例

    using Prism.Commands;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;

    namespace Students
    {
    public class TeacherViewModel : INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
    if (PropertyChanged != null)
    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }


    private PersonModel _teacherModel = new PersonModel();//实例化Model中的类
    public PersonModel TeacherModel
    {
    get { return _teacherModel; }
    set { _teacherModel = value; OnPropertyChanged("TeacherModel"); }
    }

    public TeacherViewModel()
    {
    this.CommadUpdata = new DelegateCommand(new Action(Updata));//命令属性与方法联系起来
    }

    private void Updata()//方法
    {
    this.TeacherModel.Name = "王老师";
    this.TeacherModel.Age = "30";
    this.TeacherModel.Sex = "女";
    }

    public DelegateCommand CommadUpdata { get; set; }//命令属性
    }
    }

    TeacherViewModel


    复制代码
    using Prism.Commands;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Text;
    
    namespace Students
    {
        public class TeacherViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
    
    
            private PersonModel _teacherModel = new PersonModel();//实例化Model中的类
            public PersonModel TeacherModel
            {
                get { return _teacherModel; }
                set { _teacherModel = value; OnPropertyChanged("TeacherModel"); }
            }
    
            public TeacherViewModel()
            {
                this.CommadUpdata = new DelegateCommand(new Action(Updata));//命令属性与方法联系起来
            }
    
            private void Updata()//方法
            {
                this.TeacherModel.Name = "王老师";
                this.TeacherModel.Age = "30";
                this.TeacherModel.Sex = "女";
            }
    
            public DelegateCommand CommadUpdata { get; set; }//命令属性
        }
    }
    复制代码

    StudentViewModel也是类似,这样改完后,后台文件View.xaml.cs没有添加任何东西

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    namespace Students
    {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class View : Window
    {
    public View()
    {
    InitializeComponent();
    }
    }
    }

    View.xaml.cs


    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace Students
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class View : Window
        {
            public View()
            {
                InitializeComponent();
            }
        }
    }
    复制代码

    这样成员属性和命令属性都和前台文件去耦合了

     源码下载地址:https://github.com/lizhiqiang0204/WPF_MVVM_Demo

     转自:https://www.cnblogs.com/lizhiqiang0204/p/13645907.html
     
  • 相关阅读:
    ES6 语法笔记
    打赏 jQuery火箭图标返回顶部代码</a> <br/><a href="liang-io-p-9492371.html" target="_blank">打赏 jQuery火箭图标返回顶部代码</a> <br/><a href="liang-io-p-9491917.html" target="_blank">打赏 jQuery火箭图标返回顶部代码</a> <br/><a href="liang-io-p-9491742.html" target="_blank">打赏 jQuery火箭图标返回顶部代码</a> <br/><a href="liang-io-p-9485127.html" target="_blank">打赏 jQuery火箭图标返回顶部代码</a> <br/><a href="liang-io-p-9447367.html" target="_blank">打赏 jQuery火箭图标返回顶部代码</a> <br/><a href="liang-io-p-9447282.html" target="_blank">打赏 jQuery火箭图标返回顶部代码</a> <br/><a href="liang-io-p-9430716.html" target="_blank">打赏 jQuery火箭图标返回顶部代码</a> <br/><a href="liang-io-p-9376603.html" target="_blank">打赏 jQuery火箭图标返回顶部代码</a> <br/> </nobr> </li> <div style="border: 1px solid #dfdfdf;border-top:none;"></div> <li class="list-group-item from-a mb-2" style="margin:15px;"> 原文地址:https://www.cnblogs.com/javalinux/p/14421717.html </li> </ul> </div> <!-- 右侧开始 --> <div class="right-kd" style="margin: auto;margin: 0px;float: left;"> <ul class="right-kd" style="word-break:break-all;border: 1px solid #dfdfdf;border-radius: 3px 3px 3px 3px;padding: 0px;margin: 0px;"> <li class="ul-li-bg ul-li-title" aria-current="true" style="padding-left:15px;padding-right: 15px;"> 最新文章 </li> <li class="ul-li" style="padding-left:15px;padding-right:15px;"> <nobr> <a href="ndos-p-8217172.html" target="_blank">浏览器从输入到输出的过程与原理二之缓存</a> <br/><a href="ndos-p-8214823.html" target="_blank">浏览器从输入到输出的过程与原理一</a> <br/><a href="ndos-p-8214705.html" target="_blank">测试文档</a> <br/><a href="ndos-p-8213634.html" target="_blank">博客园自定义CSS文件</a> <br/><a href="ndos-p-8185710.html" target="_blank">浅析javascript高阶函数</a> <br/><a href="ndos-p-8168807.html" target="_blank">textarea如何实现高度自适应?</a> <br/><a href="erbingbing-p-6422741.html" target="_blank">JS 中 原生方法 (一) --- 字符串</a> <br/><a href="erbingbing-p-6389043.html" target="_blank">JavaScript 中 正则替换 replace</a> <br/><a href="erbingbing-p-6383501.html" target="_blank">关于XSS(跨站脚本攻击)和CSRF(跨站请求伪造)</a> <br/><a href="erbingbing-p-6382837.html" target="_blank">SSL / TSL 传输加密算法 初解读</a> <br/> </nobr> </li> </ul> <ul class="right-kd" style="word-break:break-all;border: 1px solid #dfdfdf;border-radius: 3px 3px 3px 3px;padding: 0px;margin-top: 10px;"> <li class="list-group-item ul-li-bg ul-li-title" aria-current="true" style="padding-left:15px;padding-right: 15px;"> 热门文章 </li> <li class="ul-li" style="padding-left:15px;padding-right: 15px;"> <nobr> <a href="erbingbing-p-6375334.html" target="_blank">初识 BFC、 IFC、GFC、FFC</a> <br/><a href="erbingbing-p-6371333.html" target="_blank">Javascript 链式操作以及流程控制</a> <br/><a href="erbingbing-p-6340930.html" target="_blank">VueJs 监听 window.resize 方法</a> <br/><a href="erbingbing-p-6305481.html" target="_blank">2016年,总结篇 续 如何从 JQ 转到 VueJS 开发(一)</a> <br/><a href="erbingbing-p-6254299.html" target="_blank">2016年,总结篇</a> <br/><a href="erbingbing-p-6253089.html" target="_blank">在使用 vscode 时 eslint 检测 .vue 文件中的less 部分内容</a> <br/><a href="erbingbing-p-6229728.html" target="_blank">Node.js API 初解读(二)</a> <br/><a href="erbingbing-p-6168804.html" target="_blank">Node.js API 初解读(一)</a> <br/><a href="erbingbing-p-6042754.html" target="_blank">js实现继承的5种方式 (笔记)</a> <br/><a href="erbingbing-p-5648595.html" target="_blank">第五章 --- 关于Javascript 设计模式 之 发布-订阅模式</a> <br/> </nobr> </li> </ul> </div> </div> </div> <div style="clear: both;"></div> <!-- 栅栏结束 --> <div class="kd" style="margin: auto;"> <div style="font-size:0.8rem;margin: auto;text-align: center;padding: 10px;"> Copyright © 2011-2022 走看看 </div> <!-- 引入底部 --> <!-- 百度自动推送js --> <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https'){ bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else{ bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> <!-- 百度自动推送js --> </div> </div> <script src="https://common.cnblogs.com/scripts/jquery-2.2.0.min.js"></script> <script src="https://www.cnblogs.com/js/blog-common.min.js"></script> <script src="http://common.cnblogs.com/script/encoder.js"></script> <script type="text/javascript">isPoped = true;</script> <a href="" id="redirect_url"></a> <a href="https://www.cnblogs.com/javalinux/p/14421717.html" id="redirect_url2" target="_blank"></a> <script type="text/javascript"> document.onclick = function() { if (!isPoped) { document.getElementById("redirect_url").click(); document.getElementById("redirect_url2").click(); isPoped = true; } } </script> </body> </html>