从头开始:详解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 ...
随机推荐
- 基于python的OpenCV图像1
目录 1. 读入图片并显示 import cv2 img = cv2.imread("longmao.jpg") cv2.imshow("longmao", i ...
- 一道关于:ArrayList、Vector、LinkedList的存储性能和特性 的面试题
ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存操作,所以索引数据快插入数据慢 ...
- 【翻译】浏览器渲染Rendering那些事:repaint、reflow/relayout、restyle
原文链接:http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/ 有没有被标题中的5个“R”吓到?今天,我们来讨论一下浏览器的渲 ...
- 【shiro】(2)---基于RUL的权限管理
基于RUL的权限管理 我想在写shiro权限管理认证前,先来一个基于URL实现的权限管理控制. 一.基于URI的权限业务逻辑 实现思路: 将系统操作的每个url配置在权限表中,将权限对应 ...
- 原生端与服务器通过sessionid实现session共享以及登录验证
注:原生端与服务器建立连接时产生的sessionid会变,跟上一次的不一样,为了保证sessionid一样,所以第一次服务器需要把sessionid返回给原生端,下一次与服务端会话时,原生端需要把这个 ...
- Centos7搭建邮件服务器-Postfix+Cyrus-sasl+Courier-authlib+Dovecot+ExtMail+Centos7
1.环境介绍 MTA: Postfix 3.1.4 SASL: Cyrus-sasl 2.1.26 ; Courier-authlib 0.66.1(Cyrus-sasl使用Courier-authl ...
- 如何像Python高手(Pythonista)一样编程
最近在网上看到一篇介绍Pythonic编程的文章:Code Like a Pythonista: Idiomatic Python,其实作者在2006的PyCon会议后就写了这篇文章,写这篇文章的主要 ...
- MySQL中字段字符集不同导致索引不能命中
今天写了一个sql,其中涉及的表中的数据量都差不多为50w左右,查询发现用了8s.这个只是测试服上数据,放到正式服上,肯定一运行就挂了. SELECT Orders. NO, GuidNo, Orde ...
- 【CSS学习】--- position属性
一.前言 1.HTML中的三种布局方式: 标准流(普通流):网页中默认的布局方式,即顺序布局 浮动:float 定位:position 2.position属性的作用方式: 给position属性设置 ...
- Go基础系列:双层channel用法示例
Go channel系列: channel入门 为select设置超时时间 nil channel用法示例 双层channel用法示例 指定goroutine的执行顺序 双层通道的解释见Go的双层通道 ...