【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
学习过vue的同学都知道mvvm这个名词。从字面上理解,可能有点拗口,但是我们可以去理解一下它的优点是什么。mvc相信大家都明白,m就是model,v就是view,c就是control。model的话,一般就是数据,目前大多数就是数据库里面的data;v就是view,可以是网页,可以是前端;c的话,就是control,简单的看就是控件的各个回调函数。
当然,这是mvc。现在又出了一个mvvm。本质上,mvvm相当于提供了一种双向绑定的模式。即界面中的显示和实际的数据bind在一起。这样数据发生任何的改变,用户不需要重新渲染界面了。这对开发的同学来说,是十分方便的。为了说明双向绑定是怎么使用的,我们可以写一个简单的demo说明一下。
整个界面和之前相比较,最大的不同就是多了一个DataContext。里面有一个类,就是后面要实现的PersonViewModel。另外,在Grid里面,我们看到有四个Binding,其实是两组。每一组都有一个FirstName,一个LastName。除此之外呢,还有一个Button,它主要是演示怎么从外面给界面发数据。而里面的输入呢,相当于从界面发给数据。
出来的效果应该是这样的,
主窗口中有一个按钮,需要设计一个回调函数。它的主要目的就是利用DataContext给FirstName和LastName传值。按钮按下去之后呢,不管是txt中的内容,还是label中的内容,都会发生改变。
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 WpfApp
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var model = this.DataContext as PersonViewModel;
model.FirstName = "Tom";
model.LastName = "Cruise";
}
}
}
整个代码中,最重要的部分就是INotifyPropertyChanged的实现。xaml中我们看到了PersonViewModel这个类,到时候系统会创建一个实例。数据发生改变的时候,就会调用对应的set函数。在set函数中,我们会进一步调用子函数OnPropertyChanged,通知所有关注这个property的函数。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfApp
{
public class PersonViewModel : INotifyPropertyChanged
{
public static PersonModel _person;
private static int flag = 0;
public PersonViewModel()
{
if (flag == 0)
{
flag = 1;
_person = new PersonModel();
}
}
public string FirstName
{
get { return _person.FirstName; }
set
{
if (_person.FirstName != value)
{
_person.FirstName = value;
OnPropertyChanged(nameof(FirstName)); // invoke here
}
}
}
public string LastName
{
get { return _person.LastName; }
set
{
if (_person.LastName != value)
{
_person.LastName = value;
OnPropertyChanged(nameof(LastName)); // invoke here
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
// invoke after value was set
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class PersonModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
总结一下,前面我们说过双向绑定,它的意思就界面的修改和传递给变量,那么变量的修改也可以传递给界面。MainWindows中实现的是变量传给界面,而PersonViewModel实现的相当于界面传给变量。
编译没有问题的话,就可以开始测试了。测试的时候,我们可以在txt中输入不同的数据,下面的label也会做同步的显示。这一步测试之后,我们就可以单机一下按钮,看txt中的内容有没有同步改变。如果两者都没有问题,那么就代表mvvm测试ok了。
一开始测试的情景,
这个时候,如果我们设置一下Button,就会变成这样,