1.程序结构如图所示:

2.Model实现

在Model文件夹下新建业务类StudentModel,代码如下:

public class StudentModel : INotifyPropertyChanged
{
private int studentId;

public int StudentId
{
get { return studentId; }
set
{
studentId = value;
NotifyPropertyChanged("StudentId");
}
}

private string studentName;

public string StudentName
{
get { return studentName; }
set { studentName = value; }
}

private int studentAge;

public int StudentAge
{
get { return studentAge; }
set { studentAge = value; }
}
private string studentEmail;

public string StudentEmail
{
get { return studentEmail; }
set { studentEmail = value; }
}
private string studentSex;

public string StudentSex
{
get { return studentSex; }
set { studentSex = value; }
}

public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (propertyName != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

StudentModel类实现了接口INotifyPropertyChanged。当类实现该接口后,便可以执行绑定的客户端发出某一属性值已改变的通知。

3ViewModel实现

代码如下:

public class StudentViewModel
{
public DelegateCommand ShowCommand { get; set; }
public StudentModel Student { get; set; }
public StudentViewModel()
{
Student = new StudentModel();
ShowCommand = new DelegateCommand();
ShowCommand.ExecuteCommand = new Action<object>(ShowStudentData);
}
private void ShowStudentData(object obj)
{
Student.StudentId = 1;
Student.StudentName = "tiana";
Student.StudentAge = 20;
Student.StudentEmail = "456456646@qq.com";
Student.StudentSex = "男";
}
}
public class DelegateCommand : ICommand
{
public Action<object> ExecuteCommand = null;
public Func<object, bool> CanExecuteCommand = null;
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
if (CanExecuteCommand != null)
{
return this.CanExecuteCommand(parameter);
}
else
{
return true;
}

}

public void Execute(object parameter)
{
if (this.ExecuteCommand != null)
{
this.ExecuteCommand(parameter);
}

}
public void RaiseCanExecuteChange()
{
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, EventArgs.Empty);
}
}
}

代码中,除了定义StudentViewModel类外,还定义了DelegateCommand类,该类实现了ICommand接口。

ICommand接口中的Execute()方法用于命令的执行,CanExecute()方法用于只是当前命令在目标元素上是否可用,当这种可用性发生改变时便会触发接口中的CanExecuteChanged事件。

我们可以将实现了ICommand接口命令DelegateCommand赋值给Button(命令源)的Command属性(只有实现了ICommandSource接口的元素才拥有该属性),这样Button便与命令进行了绑定。

MainWindow界面的xaml代码如下:

<Window x:Class="WPFMVVMExample.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:WPFMVVMExample"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label Content="学号" Height="28" HorizontalAlignment="Left" Margin="54,23,0,0" Name="labelStudentId" VerticalAlignment="Top"></Label>
<TextBox Text="{Binding Student.StudentId}" IsReadOnly="True" Height="23" HorizontalAlignment="Right" Margin="0,27,289,0" Name="textBoxStudentId" VerticalAlignment="Top" Width="120"></TextBox>
<Button Command="{Binding ShowCommand}" Content="显示" Height="23" HorizontalAlignment="Left" Margin="345,27,0,0" Name="buttonShow" VerticalAlignment="Top" Width="75"></Button>
</Grid>
</Window>

MainWindow后端代码如下:

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new StudentViewModel();
}
}
}

5运行程序

运行程序,点击“”显示“按钮”,即将数据绑定至界面显示

6.说明

wpf中使用mvvm可以降低UI显示与后端逻辑代码的耦合度,即便换界面时,只需要修改很少的逻辑代码就可以实现,甚至不用修改。

在wpf中使用数据绑定机制,当数据变化后,数据会通知界面变更的发生,而不需要通过访问界面元素来修改值,这样后端逻辑代码中也就不必操作或者很少操作界面的元素了。

使用MVVM,可以很好的配合WPF的数据绑定机制来实现ui与逻辑代码的分离,mvvm中的view表示界面,负责页面显示,viewmodel负责逻辑处理,包括准备绑定的数据和命令,viewmodel通过view的datacontext属性绑定至view,model为业务模型,共viewmodel使用。

7.架构

如果你读到这里,你会发现,如果你以后要使用这种方式,以上的代码大多都是在重复:实现INPC(INotifyPropertyChanged)或创建Command这其实就是大部分MVVM 的样板,所以我们可以将实现INPC放到一个基类中,我们把它叫做“ObservableObject”。对于RelayCommand类,我们可以将其移动到我们的.net类库中。这就是所有的mvvm框架开始所做的(如Prism,Caliburn)。

wpf mvvm 实例的更多相关文章

  1. WPF MVVM实例三

    在没给大家讲解wpf mwm示例之前先给大家简单说下MVVM理论知识: WPF技术的主要特点是数据驱动UI,所以在使用WPF技术开发的过程中是以数据为核心的,WPF提供了数据绑定机制,当数据发生变化时 ...

  2. 一个简单的WPF MVVM实例【转载】

    引用地址:http://blog.csdn.net/yl2isoft/article/details/20838149 1 新建WPF 应用程序WPFMVVMExample 程序结构如下图所示. 2  ...

  3. WPF/MVVM 快速开始指南(译)(转)

    WPF/MVVM 快速开始指南(译) 本篇文章是Barry Lapthorn创作的,感觉写得很好,翻译一下,做个纪念.由于英文水平实在太烂,所以翻译有错或者译得不好的地方请多指正.另外由于原文是针对W ...

  4. WPF自学入门(十一)WPF MVVM模式Command命令

    在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式.正如上一篇文章中在开始说的,MVVM的目的是为了最大限度地降低了 ...

  5. WPF MVVM UI分离之《交互与数据分离》 基础才是重中之重~delegate里的Invoke和BeginInvoke 将不确定变为确定系列~目录(“机器最能证明一切”) 爱上MVC3系列~全局异常处理与异常日志 基础才是重中之重~lock和monitor的区别 将不确定变成确定~我想监视我的对象,如果是某个值,就叫另一些方法自动运行 将不确定变成确定~LINQ DBML模型可以对

    WPF MVVM UI分离之<交互与数据分离>   在我们使用WPF过程中,不可避免并且超级喜欢使用MVVM框架. 那么,使用MVVM的出发点是视觉与业务逻辑分离,即UI与数据分离 诸如下 ...

  6. WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍

    WPF自学入门(十一)WPF MVVM模式Command命令   在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式 ...

  7. WPF MVVM 从Prism中学习设计模式之Event Aggregator 模式

    Prism简介 Prism是由微软Patterns & Practices团队开发的项目,目的在于帮助开发人员构建松散耦合的.更灵活.更易于维护并且更易于测试的WPF应用或是Silverlig ...

  8. .NET Core 3 WPF MVVM框架 Prism系列之事件聚合器

    本文将介绍如何在.NET Core3环境下使用MVVM框架Prism的使用事件聚合器实现模块间的通信 一.事件聚合器  在上一篇 .NET Core 3 WPF MVVM框架 Prism系列之模块化 ...

  9. WPF/MVVM Quick Start Tutorial - WPF/MVVM 快速入门教程 -原文,翻译及一点自己的补充

    转载自 https://www.codeproject.com/articles/165368/wpf-mvvm-quick-start-tutorial WPF/MVVM Quick Start T ...

随机推荐

  1. Entity Framework查询

    Entity Framework是个好东西,虽然没有Hibernate功能强大,但使用更简便.今天整理一下常见SQL如何用EF来表达,Func形式和Linq形式都会列出来(本人更喜欢Func形式). ...

  2. Go 语言基础(一)

    1.GO语言的第一个程序: package main import "fmt" func main() { fmt.Println("hello,world!" ...

  3. 🍓 vue循环渲染本地图片不显示? 🍓

    teamList: [{ title: '大数据拍牌', imgUrl: './img/data.jpg', introduce: '5星服务:强烈推荐', cost: '15000', bail: ...

  4. 用户态与内核态 & 文件流与文件描述符 简介

    用户态和内核态 程序代码的依赖和调用关系如下图所示: Lib:标准ASCI C函数,几乎所有的平台都支持该库函数,因此依赖该库的程序可移植性好: System Function:系统调用函数,与系统内 ...

  5. RTF文件格式

    文档地址 首先给出一个生成最简单的RTF文件的脚本 f=open('hello_world.rtf','w') padding='{\\rtf1\\ansi' padding+=' Hello Wor ...

  6. IEnumerable<T>和IQueryable<T>区别

    LINQ查询方法一共提供了两种扩展方法,在System.Linq命名空间下,有两个静态类:Enumerable类,它针对继承了IEnumerable<T>接口的集合进行扩展:Queryab ...

  7. SpringMVC+Spring+Hibernate整合开发

    最近突然想认真研究下java web常用框架,虽然现在一直在用,但实现的整体流程不是很了解,就在网上搜索资料,尝试自己搭建,以下是自己的搭建及测试过程. 一.准备工作: 1/安装并配置java运行环境 ...

  8. 微信小程序换皮肤,动态切换菜单栏和导航栏的样式,动态修改TabBar和NavigationBar

    在做微信小程序换皮肤的时候,需要动态修改菜单栏(TabBar)和导航栏(NavigationBar) 但是在小程序中它们的样式是写在app.json里面,而且app.json是静态编译,运行时哪怕你修 ...

  9. Javascript 精简语法介绍

    1. 取整同时转成数值型: '10.567890'|0 结果: 10 '10.567890'^0 结果: 10 -2.23456789|0 结果: -2 ~~-2.23456789 结果: -2 2. ...

  10. jquery源码解析日常

    介绍:JQuery是继prototype之后又一个优秀的Javascript库.它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器(IE 6.0+, FF1.5+, Safari 2.0+, Op ...