从头开始:详解MVVM、MVVMLight
- 究竟为什么要学习MVVM?
相信大部分同学在刚开始接触MVVM的时候(包括我自己),心里默默在想这究竟是什么玩意?一个简单的功能要写一大段代码才能完成,在看到MVVM的核心目标: 1.让UI界面与逻辑能够很好地分离又协同工作。 2.让逻辑代码更具有可测试性。 会觉得我不把我的UI和逻辑分离,我的代码一样可以很好的分离又协同工作; 会觉得我不用MVVM我的代码一样测得好好的; 在这里,我先不说什么。我觉得这个需要自己意会了才能判断出自己的观点是正确的还是错误的。
- 开始学习MVVM之前:
1.在开始学习MVVM你应该具备基本的C#(WPF或者SliverLight)的变成知识。如果你现在对这些还不熟悉,不建议先看这个,毕竟凡事都需要一步一步来。 2.本文主要拿WPF程序作为例子。例子源代码提供下载。
- 学习绑定(Binding)
1.新建一个WPF项目
2.新建一个类:Model,Model代码如下:
class Model
{
private string _text; public string Text
{
get { return _text; }
set { _text = value; }
} public Model()
{
_text = "HelloWorld";
}
}
Model代码
3.在MainWindows中放一个TextBox:
<TextBlock Text="{Binding Text}"/>
TextBox的Text并没有显示制定值,而是绑定在一个名为"Text"的变量上面。但是目前这个程序还无法运行,因为编译器不知道“Text”这个变量是什么东西,所以需要给编译器指明这个“Text”在哪里。
我们的目的是要把TextBox的Text属性绑定在Model类的Text属性上面,设置数据上下文(DataContext)就可以让编译器找到“Text”这个变量。
<Window x:Class="学习绑定.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:学习绑定"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:Model/>
</Window.DataContext>
<Grid>
<TextBlock Text="{Binding Text}"/>
</Grid>
</Window>
现在程序应该可以运行了,效果如下:

刚开始学可以简单粗暴一点,绑定就是把一个值绑定在另一个值上面。绑定也是一个比较复杂的东西,这里不细讲,需要了解的朋友可以自己搜索下,太多的资料的。
在你觉得自己了解绑定之后就可以往下看了。
- 开始第一个MVVM程序
这个程序很简单,在界面中放置一个文本框和一个按钮很简单。文本框初始化的值为0.在点击按钮后,文本框的值加1.
界面XAML如下:
<Window x:Class="第一个MVVM程序.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TextBlock x:Name="Tb1"/>
<Button Click="Button_Click" Content="点击我加1" Margin="0,10,0,0" HorizontalAlignment="Left"/>
</StackPanel>
</Window>
在没有了解MVVM之前,我们实现这个的过程很可能是这样:
public partial class MainWindow : Window
{
private int Num; public MainWindow()
{
InitializeComponent();
Num = ;
Tb1.Text = Num.ToString();
} private void Button_Click(object sender, RoutedEventArgs e)
{
Num++;
Tb1.Text = Num.ToString();
}
}
实现后运行的效果如下:

根据上面学的绑定的知识,我们通过绑定的方式实现这个功能。
1.建立一个类Model
class Model
{
private int _num; public int Num
{
get { return _num; }
set { _num = value; }
} public Model()
{
_num = ;
}
}
2.将文本框的Text属性绑定在Model的Text上面。(记住声明DataContext)
绑定之后,程序的Xaml代码就变成这样了:
<Window x:Class="第一个MVVM程序.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:第一个MVVM程序"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:Model/>
</Window.DataContext>
<StackPanel>
<TextBlock x:Name="Tb1" Text="{Binding Num}"/>
<Button Click="Button_Click" Content="点击我加1" Margin="0,10,0,0" HorizontalAlignment="Left"/>
</StackPanel>
</Window>
3.然后相应按钮的响应事件:
public partial class MainWindow : Window
{
private Model model; public MainWindow()
{
InitializeComponent();
/*Xaml里面通过这样的方式为窗体添加了一个数据上下文
* <Window.DataContext>
* <local:Model/>
* </Window.DataContext>
* 现在由于文本框的值绑定在Model的Text上面了,所有需要获取这个Model才能改变Text的值,
* 改变了Text的值才能改变文本框显示的值
*/
model = this.DataContext as Model;
} private void Button_Click(object sender, RoutedEventArgs e)
{
model.Num++;
}
}
4.编译通过,开始运行。点击按钮后........妈蛋怎么文本框的值没有变?其实原因很简单。
我们先理清楚我们到目前为止在这个程序里面做了什么。
首先,我们建立了一个Model类,并在类里面写了一个属性"Text";
然后,我们将TextBlock的Text属性绑定在了Model的“Text”属性上面;
最后,我们发现在更改了Model的Text值后,TextBlock的值并没有发生变化。
可以确定的是,Model类的Text值肯定变化了。既然Model类的Text发生了变化,绑定也绑了,那么TextBlock的值怎么不变化?
实际上是因为你没有通知界面Text的值变了,所以界面就不知道实际上Model里面的Text已经发生变化,自然就没有必要更新界面了。
了解了问题产生的原因后,我们需要在Text发生变化后通知界面.为此,类Model需要实现"INotifyPropertyChanged"借口。从字面上就可以发现这个接口的意思就是“通知属性变化”。
实现后,Model类就变成这样了:
class Model:INotifyPropertyChanged
{
private int _num; public int Num
{
get { return _num; }
set
{
if(_num != value)
{
_num = value;
NotifyPropertyChanged("Num");
}
}
} public Model()
{
_num = ;
} public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string name)
{
if(PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
运行后,效果如下:

对于初学者,很难一下理解透这些过程和原理。其实你需要记住:但凡你想要在你的数据源发生变化,目标的值跟着发生变化,你都需要在数据源发生变化的时候通知目标。
未完待续。
从头开始:详解MVVM、MVVMLight的更多相关文章
- Vue基础开发入门之简单语法知识梳理(思维导图详解)
基于个人写的以下关于Vue框架基础学习的三篇随笔,在此基础上,做一个阶段性的知识总结,以此来检验自己对Vue这一段时间学习的成果,内容不多,但很值得一看.(思维导图详解)
- MVVMLight消息通知实现机制详解(二)
接上文 MVVMLight消息通知实现机制详解(一) 该工具的内部主要逻辑是以字典模式进行储存持有订阅对象设置的传入参数Type类型.Key值.Action.Target(订阅对象本身) 在发生订阅事 ...
- MVVMLight消息通知实现机制详解(一)
最近对委托.事件的订阅使用的太多,订阅与被订阅之间的绑定约束非常...麻烦,所以翻了下MVVMLight源码找出这段可以拿出来用的部分,详情见下: 一.开发中遇到的问题: 场景1:ClassA中存在事 ...
- 热门前沿知识相关面试问题-MVC/MVP/MVVM架构设计模式面试问题详解
MVC[最常用]: MVC的定义:M:业务逻辑处理.[业务MODEL]V:处理数据显示的部分.[如xml布局文件]C:Activity处理用户交互的问题.[也就是Activity在MVC中扮演着C的角 ...
- ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借
ASP.NET MVC深入浅出系列(持续更新) 一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...
- Android中Activity运行时屏幕方向与显示方式详解
现在我们的手机一般都内置有方向感应器,手机屏幕会根据所处位置自动进行横竖屏切换(前提是未锁定屏幕方向).但有时我们的应用程序仅限在横屏或者竖屏状态下才可以运行,此时我们需要锁定该程序Activity运 ...
- iOS开发——高级技术&本地化与国际化详解
本地化与国际化详解 效果如下: 英语: 中文: 具体实现如下: ...
- 服务器.htaccess 详解以及 .htaccess 参数说明(转载)
htaccess文件(或者”分布式配置文件”)提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录.作为用户,所能使用的命令受到限 ...
- python之OS模块详解
python之OS模块详解 ^_^,步入第二个模块世界----->OS 常见函数列表 os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows ...
随机推荐
- vmdk多文件合成单文件并导入
如果创建时,目录中有多个vmdk文件,可以将其合成一个,方便导到其他地方运行,如图所示 win下cmd命令,找到安装vmware目录,合并的命令如下 vmware-vdiskmanager.exe - ...
- Android--UI之Radio、Check、Toggle
前言 这篇博客讲解一下Android平台下,RadioButton.CheckBox以及ToggleButton三个控件的用法,因为这三个控件之中都存在一个选中或是没选中的状态,所以放在一起讲解. 这 ...
- 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装OpenCV(离线方式和在线方式)(图文详解)
不多说,直接上干货! 说明: Anaconda2-5.0.0-Windows-x86_64.exe安装下来,默认的Python2.7 Anaconda3-4.2.0-Windows-x86_64.ex ...
- Java 容器源码分析之 Set
Set 表示由无重复对象组成的集合,也是集合框架中重要的一种集合类型,直接扩展自 Collection 接口.在一个 Set 中,不能有两个引用指向同一个对象,或两个指向 null 的引用.如果对象 ...
- spring学习(四) ———— 整合web项目(SSH)
清楚了spring的IOC 和 AOP,最后一篇就来整合SSH框架把,记录下来,以后应该会用的到. --WH 一.web项目中如何使用spring? 当tomcat启动时,就应该加载spring的配置 ...
- python面向对象入门(1):从代码复用开始
本文从代码复用的角度一步一步演示如何从python普通代码进化到面向对象,并通过代码去解释一些面向对象的理论.所以,本文前面的内容都是非面向对象的语法实现方式,只有在最结尾才给出了面向对象的简单语法介 ...
- MySQL行转列
IF(expr1,expr2,expr3) 如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2; 否则 ...
- Java虚拟机——类的结构与加载
1.为什么Java可以跨平台 因为有java虚拟机,跨平台是因为字节码即class文件具有平台无关性,java代码会经过java虚拟机转换为字节码 2.class文件的结构 class文件主要是以8位 ...
- Linux配置2个或多个Tomcat同时运行
一.问题说明今天操作Linux部署项目的时候,公司领导要求,只给一个服务器,但是有2个项目要部署,而且需要独立分开运行. 二.解决方法Linux配置两个或多个Tomcat,一个Tomcat对应部署一个 ...
- .net使用websocket
专业挖坑21年 1.前 言 网上找了很多资料,可能是自己找的路子不对吧,都找不到适合我这样萌新的文章,大多.net环境使用的websocket都是在说一个通信的案例,学起来的确很吃力,自己也挖 ...