在看绑定之前,我们先来聊聊绑定涉及到的WPF编程框架。今天先简单写一下MVVM框架,尽量让大家知道这个框架是什么样子的,然后后面举个例子。
首先有一个内容需要先一步了解,就是Winform和WPF之间的不同,不知道各位有没有用过Winform,在使用Winform的时候,我们一般都是直接拖动控件,然后给每一个控件设计事件即可。比如拖动一个按钮控件,设置其点击事件,这种模式一般称为事件驱动。而WPF是基于数据驱动的,WPF是基于XAML语言的,其常用的MVVM框架,会将窗体中的控件属性与后台数据相绑定,进而完成前后端解耦的目标,而MVVM框架中最主要的内容就是绑定。
然后具体看一下MVVM,这是一种前后端开发分离的一种开发模式,这个模式把项目分成了以下三个部分。
①View:项目的UI界面
②ViewModel:项目的所有数据保存在此。
③Model:我们为项目设计的数据结构
我们看一下这三个部分,我们在做一个上位机的时,其中会包括很多个页面,这些UI页面对应的就是MVVM中的View,我们在设计页面时,肯定是为了让这个页面来显示一些我们需要的设备信息,这些设备的信息我们会将其统一管理起来,放在一个ViewModel里面,而这些设备的信息,可能会因为不同的设备而需要不同的数据结构来存储信息,这些具体的数据结构,我们一般称为MVVM中的Model。
从开发的角度整体上看一下,在基于MVVM的WPF项目开发时,我们设计UI界面时,我们只需要搭好一个显示数据的框架即可,然后为UI的显示数据在ViewModel中创建具体的绑定对象,这些绑定对象,就是基于我们设计的Model创建的实例,这样整个项目就可以搭建起来了。
上面只是简单的写了一下MVVM的最基础内容,下面看一个例子。
View:
<Window x:Class="binding_mvvm.MainWindow"
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:binding_mvvm"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" x:Name="window">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="Name:" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="35"/>
<TextBlock Text="Age:" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="35"/>
<TextBlock Text="Score:" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="35"/>
<TextBox Text="{Binding student._Name}" FontSize="35" Grid.Column="1" MinWidth="550" Grid.Row="0" HorizontalAlignment="Left" Height="50"/>
<TextBox Text="{Binding student._Age}" FontSize="35" Grid.Column="1" MinWidth="550" Grid.Row="1" HorizontalAlignment="Left" Height="50"/>
<TextBox Text="{Binding student._Score}" FontSize="35" Grid.Column="1" MinWidth="550" Grid.Row="2" HorizontalAlignment="Left" Height="50"/>
</Grid>
</Window>
Model:
using System.ComponentModel;
namespace binding_mvvm.Model
{
public class StudentModel:INotifyPropertyChanged
{
private string Name;
public string _Name
{
get { return Name; }
set { Name = value; OnPropertyChanged(_Name); }
}
private int Age;
public int _Age
{
get { return Age; }
set { Age = value; OnPropertyChanged(_Age.ToString()); }
}
private int Score;
public int _Score
{
get { return Score; }
set { Score = value; OnPropertyChanged(_Score.ToString()); }
}
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
ViewModel:
using binding_mvvm.Model;
namespace binding_mvvm.ViewModel
{
public class MainViewModel
{
private StudentModel Student;
public StudentModel student
{
get { return Student; }
set { Student = value; }
}
public MainViewModel()
{
student = new StudentModel()
{
_Name = "张三",
_Age = 18,
_Score = 580,
};
}
}
}
后端:
using binding_mvvm.Model;
using binding_mvvm.ViewModel;
using System.Windows;
namespace binding_mvvm
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MainViewModel student1=new MainViewModel();
this.DataContext = student1;
}
}
}
运行结果:
可以看出,后台的数据已经绑定到前端了。
然后就这个小案例中的部分做一点解释。
①Text="{Binding student._Name}"
这个绑定的格式后面会总结,这里只需要明白这个是跟后端的student._Name绑上了就行。
②MainViewModel student1=new MainViewModel();
this.DataContext = student1;
这个就是指明数据上下文的,前面有写过。
③INotifyPropertyChanged
这是一个接口,这个接口的作用,就是告诉前端,后端绑定的数据的值是多少。所以需要绑定到前端的数据都需要使用这个接口。
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
这个代码就是接口实例化,这段代码需要背诵,因为后续的实现代码几乎不需要改动。
private int Score;
public int _Score
{
get { return Score; }
set { Score = value; OnPropertyChanged(_Score.ToString()); }
}
在具体需要使用的属性的set部分加上接口函数的调用即可。
通过上面的例子,应该可以大概理解MVVM框架是什么样的了,然后学习绑定的时候就知道其在框架中的地位。后面我们一起学习更多绑定的内容,进而加深对MVVM的认识。