一、概述
MVVM 是 Model view viewModel 的简写。MVVM模式有助于将应用程序的业务和表示逻辑与用户界面清晰分离。
几个概念的说明:
- model :数据,界面中需要的数据,最好不要加逻辑代码
- view : 视图就是用户看到的UI结构 xaml 文件
- viewModel : 业务逻辑代码
- 绑定器:声明性数据和命令绑定隐含在MVVM模式中。
使用MVVM模式并不会减少代码量,反而会增加很多代码。MVVM设计模式的根本目的是把界面和业务逻辑分离。
WPF的依赖属性,数据绑定等机制,很好地帮助我们实现MVVM模式,基本可以做到在界面层不出现业务逻辑代码。
二、mvvm 的实现
首先,新建 views models viewModels文件夹,用于存放不同模型
以简单的加法操作为例。
因为使用mvvm模式后,数据都是c#后端代码提供,前端使用后端的数据,只能通过值绑定的方式,同时如果后端业务逻辑导致数据改动,那么就需要后端去将这一改动通知到前端去。
- 前端绑定值,通过 {Binding 数据名} 的方式去绑定。
- 前端绑定事件的话,需要在viewModel层实现 Icommand 接口,以提供命令绑定事件 ,前端通过 {Binding 数据名}
- 后端通知前端数据修改,则需要实现一个 INotifyPropertyChanged 的接口,通过该接口中的 PropertyChangedEventArgs(“监听的业务操作名称”)去通知给前端。
(一)Command类 实现命令接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace WpfMvvM
{
public class Command : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
DoExecute?.Invoke();
}
public Action DoExecute { get; set; }
}
}
(二)model层
model层即数据层,
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfMvvM.Models
{
public class AddModule:INotifyPropertyChanged // 实现INotifyPropertyChanged接口
{
public event PropertyChangedEventHandler PropertyChanged;
public int Num1 { get; set; } = 10;
public int Num2 { get; set; } = 20;
private int _Rs;
public int Rs
{
get { return _Rs; }
set {
_Rs = value;
// 事件委托通知 new PropertyChangedEventArgs("xx") xx为数据属性名
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Rs"));
}
}
public Command BtnCommand { get; set; } // 命令属性
}
}
(三)ViewModel 层
viewModel层,用来进行业务处理,操控model层的数据,将model层注入为其属性
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using WpfMvvM.Models;
namespace WpfMvvM.ViewModels
{
public class AddViewModel
{
// model 层数据注入
public AddModule Model {
get; set; } = new AddModule();
// 空构造器,为model层绑定命令及事件通知
public AddViewModel()
{
Model.BtnCommand = new Command();
Model.BtnCommand.DoExecute=new Action(Add);
}
// 业务逻辑方法 加法
private void Add()
{
Model.Rs = Model.Num1 + Model.Num2;
}
}
}
(四)view 层
- view层 xaml部分
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontSize" Value="33"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontSize" Value="33"/>
<Setter Property="Width" Value="300"/>
</Style>
<Style TargetType="Button">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FontSize" Value="33"/>
</Style>
</Window.Resources>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="数字1" Grid.Row="0" Grid.Column="0"/>
<TextBlock Text="数字2" Grid.Row="1" Grid.Column="0"/>
<TextBlock Text="操作" Grid.Row="2" Grid.Column="0"/>
<TextBlock Text="结果" Grid.Row="3" Grid.Column="0"/>
<TextBox Text="{Binding Model.Num1}" Grid.Row="0" Grid.Column="1"/>
<TextBox Text="{Binding Model.Num2}" Grid.Row="1" Grid.Column="1"/>
<Button Content="加法" Command="{Binding Model.BtnCommand}" Grid.Row="2" Grid.Column="1" Width="300"/>
<TextBox Text="{Binding Model.Rs}" Grid.Row="3" Grid.Column="1"/>
</Grid>
- view层 cs部分
namespace WpfMvvM.views
{
/// <summary>
/// AddView.xaml 的交互逻辑
/// </summary>
public partial class AddView : Window
{
public AddView()
{
InitializeComponent();
// 设置当前窗体的数据上下文 为 AddViewModel 模型
this.DataContext = new AddViewModel();
}
}
}
view层的Cs代码部分几乎为空,只写了当前的数据上下文环境为 ViewModel 模型。
点击按钮后触发,同时结果数据进行更新