• 究竟为什么要学习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的更多相关文章

  1. Vue基础开发入门之简单语法知识梳理(思维导图详解)

    基于个人写的以下关于Vue框架基础学习的三篇随笔,在此基础上,做一个阶段性的知识总结,以此来检验自己对Vue这一段时间学习的成果,内容不多,但很值得一看.(思维导图详解)

  2. MVVMLight消息通知实现机制详解(二)

    接上文 MVVMLight消息通知实现机制详解(一) 该工具的内部主要逻辑是以字典模式进行储存持有订阅对象设置的传入参数Type类型.Key值.Action.Target(订阅对象本身) 在发生订阅事 ...

  3. MVVMLight消息通知实现机制详解(一)

    最近对委托.事件的订阅使用的太多,订阅与被订阅之间的绑定约束非常...麻烦,所以翻了下MVVMLight源码找出这段可以拿出来用的部分,详情见下: 一.开发中遇到的问题: 场景1:ClassA中存在事 ...

  4. 热门前沿知识相关面试问题-MVC/MVP/MVVM架构设计模式面试问题详解

    MVC[最常用]: MVC的定义:M:业务逻辑处理.[业务MODEL]V:处理数据显示的部分.[如xml布局文件]C:Activity处理用户交互的问题.[也就是Activity在MVC中扮演着C的角 ...

  5. 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的无状态模 ...

  6. Android中Activity运行时屏幕方向与显示方式详解

    现在我们的手机一般都内置有方向感应器,手机屏幕会根据所处位置自动进行横竖屏切换(前提是未锁定屏幕方向).但有时我们的应用程序仅限在横屏或者竖屏状态下才可以运行,此时我们需要锁定该程序Activity运 ...

  7. iOS开发——高级技术&本地化与国际化详解

    本地化与国际化详解 效果如下:   英语:                                                                    中文: 具体实现如下: ...

  8. 服务器.htaccess 详解以及 .htaccess 参数说明(转载)

    htaccess文件(或者”分布式配置文件”)提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录.作为用户,所能使用的命令受到限 ...

  9. python之OS模块详解

    python之OS模块详解 ^_^,步入第二个模块世界----->OS 常见函数列表 os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows ...

随机推荐

  1. java mongodb的MongoOptions生产级配置

    autoConnectRetry仅仅意味着驱动程序会自动尝试重新连接到意外断开连接后在服务器(一个或多个).在生产环境中,您通常需要将此设置为true. connectionsPerHost是物理连接 ...

  2. linux 清空历史命令

    系统版本:CentOS 6 history -c 命令可以清空当前窗口的历史输出命令. 要彻底删除历史命令可以有如下几种方式: 在当前用户的-目录下执行: 方式1: echo > .bash_h ...

  3. 项目总结二:人脸识别项目(Face Recognition for the Happy House)

    一.人脸验证问题(face verification)与人脸识别问题(face recognition) 1.人脸验证问题(face verification):           输入       ...

  4. 解决 Nginx 400 Bad Request 问题(WebSocket)

    400 Bad Request 是一种 HTTP 错误状态码.HTTP/1.1 对 400 Bad Request的定义主要是: 语义有误,当前请求无法被服务器理解 请求参数有误 丢包导致异常 Goo ...

  5. 拿到BAT等大厂offer以后,我发现了关于秋招的一些真相

    关于秋招的一些真相 ​ 微信公众号[程序员江湖] 作者陆小凤,985 软件硕士,阿里 Java 研发工程师,在技术校园招聘.自学编程.计算机考研等方面有丰富经验和独到见解,目前致力于分享程序员干货和学 ...

  6. 在微信小程序中使用图表

    前言:网上有许多的图表库,如:Echarts.Tau Charts.ChartJS等等,具体自行百度. 这次我们使用的是:Echarts 官方教程:点击查看 Echarts下载地址:飞机直达 1.下载 ...

  7. web进修之—Hibernate 类型(4)

    本片包含Hibernate的两种类型的简单介绍和集合类型的映射. Hibernate中的两种类型: Entity 自己掌控自己的生命周期,比如Person有addrss属性(关联到另外一张表).age ...

  8. spring-boot(二)

    学习文章来自:http://www.ityouknow.com/spring-boot.html web开发 spring boot web开发非常的简单,其中包括常用的json输出.filters. ...

  9. vue开发中,build时css打包报错

    vue在打包的时候css报错,首先声明的这个并没有解决webpack本身的问题,本来这个也是一个警示,不会影响代码正常运行 这个是因为我在多个页面引入了同一个css文件,webpack打包时候对css ...

  10. SHELL脚本--数学运算和bc命令

    bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 使用let.(()).$(())或$[]进行基本的整数运算,使 ...