WPF学习07:MVVM 预备知识之数据绑定
MVVM是一种模式,而WPF的数据绑定机制是一种WPF内建的功能集,两者是不相关的。
但是,借助WPF各种内建功能集,如数据绑定、命令、数据模板,我们可以高效的在WPF上实现MVVM。因此,我们需要对各种MVVM相关的WPF内建功能集进行了解,才能在扎实的基础上对MVVM进行学习与实践。
本文是WPF学习03:Element Binding的后续,将说明实现数据绑定的三个重点:DataContext INotifyPropertyChanged IValueConverter
MVVM简介
MVVM将User Interface切成了3个部分,View、Model、View Model.
三个部分区分如下:
View:界面代码,并完成数据可视化。
Model:一系列我们与业务层交互的类。
View Model:1.将Model中需要显示的部分,转化为对View友好的数据。 2.管理View与View之间的交互。

依赖关系如上图所示,V依赖于VM,反之不应该成立,VM依赖于M,反之亦不应成立。
在完成了对数据绑定、命令、数据模板的理解后,我们再重新回来解释MVVM。
DataContext
在WPF学习03:Element Binding中,我们只研究了如何在控件间实现数据绑定,在不指定ElementName时,Binding会在Source与RelativeSource也没有设置的情况下,一级一级的寻找DataContext,直到找到。
例子:

<StackPanel HorizontalAlignment="Center" TextBlock.Foreground="#019AFF" DataContext="{x:Static Colors.White}">
<!--指定Path,绑定对象的某个属性-->
<TextBlock Text="{Binding Path=R}"></TextBlock>
<TextBlock Text="{Binding Path=G}"></TextBlock>
<TextBlock Text="{Binding Path=B}"></TextBlock>
<!--不指定Path,绑定整个对象-->
<TextBlock Text="{Binding}"></TextBlock>
</StackPanel>
比较常用的情况下,我们将DataContext设置在最顶层元素,一般情况下为Window。
我们可以在后台代码中配置DataContext:
public class Person
{
private Int32 _age; public Int32 Age
{
get { return _age; }
set { _age = value; }
} private String _name; public String Name
{
get { return _name; }
set { _name = value; }
}
} private void Window_Loaded(object sender, RoutedEventArgs e)
{
person = new Person() { Name = "Kenny", Age = 30 };
this.DataContext = person;
} private void Button_Click(object sender, RoutedEventArgs e)
{
person.Name = "John Locke";
person.Age = 40;
}
XAML做的改动:
<StackPanel HorizontalAlignment="Center" TextBlock.Foreground="#019AFF">
<TextBlock Text="{Binding Path=Name}"></TextBlock>
<TextBlock Text="{Binding Path=Age}"></TextBlock>
<Button Click="Button_Click">Click me</Button>
</StackPanel>
效果如下:

我们可以看到的确显示了期望值,但是如果点击按键的话,是看不到任何变化的,接下来即解释原因与解决方法。
INotifyPropertyChanged
WPF内建的数据绑定机制中,Dependency Property不需额外做任何配置,即可在一般情况下建立数据绑定关系。WPF自建控件的各类属性都是依赖属性经传统的.Net属性包装而成。
如果我们希望将数据绑定的源设为我们自己定义的对象的属性,且该属性不为依赖属性,那么就只有靠实现INotifyPropertyChanged接口,并在相应的属性改变时调用PropertyChanged事件以通知目标元素。
我们将之前的后台代码做如下的改动:
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Int32 _age;
public Int32 Age
{
get { return _age; }
set {
_age = value;
if (PropertyChanged != null)
PropertyChanged.Invoke(this,new PropertyChangedEventArgs("Age"));
}
} private String _name;
public String Name
{
get { return _name; }
set {
_name = value;
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
}
} }
效果如下:

IValueConverter
某些特殊的时候,源属性与目标属性是无法连接,需要进行转换,这时,就需要用到ValueConverter.直接给个例子:
数据绑定实现根据年龄不同,文字显示同颜色,效果:


XAML代码:
<TextBlock Text="{Binding Path=Name}"></TextBlock>
<TextBlock Name="AgeTextBlock" Text="{Binding Path=Age}">
<TextBlock.Foreground>
<Binding Path="Age">
<Binding.Converter>
<local:TextBlockColorValueConverter></local:TextBlockColorValueConverter>
</Binding.Converter>
</Binding>
</TextBlock.Foreground>
</TextBlock>
后台代码:
[ValueConversion(typeof(Boolean), typeof(Int32))]
public class TextBlockColorValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if ((int)value < 18)
return new SolidColorBrush(Colors.Violet);
else
return new SolidColorBrush(Colors.Red);
} //这里用不上数据从目标返回源,故返回null
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
数据绑定的后台代码实现
之前的数据绑定都是用XAML实现的,在此给出后台代码实现数据绑定的方法,实现刚才的例子:
首先给两个控件标个Name,并去掉之前的所有绑定相关代码:
<TextBlock Name="NameTextBlock"></TextBlock>
<TextBlock Name="AgeTextBlock"></TextBlock>
后台代码:
var bind = new Binding("Name")
{
Source = person,
};
NameTextBlock.SetBinding(TextBlock.TextProperty, bind);
bind = new Binding("Age")
{
Source = person,
};
AgeTextBlock.SetBinding(TextBlock.TextProperty, bind);
bind = new Binding("Age")
{
Source = person,
Converter = new TextBlockColorValueConverter()
};
AgeTextBlock.SetBinding(TextBlock.ForegroundProperty, bind);
效果与之前一致。
WPF学习07:MVVM 预备知识之数据绑定的更多相关文章
- WPF学习08:MVVM 预备知识之COMMAND
WPF内建的COMMAND是GOF 提出的23种设计模式中,命令模式的实现. 本文是WPF学习07:MVVM 预备知识之数据绑定的后续,将说明实现COMMAND的三个重点:ICommand Comm ...
- WPF学习笔记:(一)数据绑定与DataContext
前一段半心半意地学习了一下WPF,是从控件入手的,发现巨容易,甚至有些无趣.昨天面试,被问到了很多WPF的特性的东西,直接就傻了.于是乎,还是要去深刻的学习一下WPF.刚刚试了一下数据绑定,几次都没有 ...
- WPF学习笔记(一):数据绑定之元素到元素绑定
前言 作为一只菜鸟,之前学了一段时间的WPF,但是没有总结,过了一学期发现好多东西都忘记了,很多东西还是需要记下来,以备后续复习. 数据绑定在事件中应用非常广泛,可以有效地减少代码量,那么什么是数据绑 ...
- 《视觉SLAM十四讲》学习日志(一)——预备知识
SLAM简介 : SLAM是 Simultaneous Localization and Mapping 的缩写,中文译作 " 同时定位与地图构建 ".它是指搭载特定传感器的主题, ...
- WPF学习笔记一 依赖属性及其数据绑定
本文想通过由浅入深的讲解让读者比较深的理解依赖属性. 首先,我们回顾一下依赖属性的发展历史. 最初,人们提出面向对象编程时,并没有属性这个说法,当时叫做成员变量.一个对象由成员变量和成员函数组成,如 ...
- WPF学习笔记:(二)数据绑定模式与INotifyPropertyChanged接口
数据绑定模式共有四种:OneTime.OneWay.OneWayToSource和TwoWay,默认是TwoWay.一般来说,完成数据绑定要有三个要点:目标属性是依赖属性.绑定设置和实现了INotif ...
- WPF学习09:数据绑定之 Binding to List Data
从WPF学习03:Element Binding我们可以实现控件属性与控件属性的绑定. 从WPF学习07:MVVM 预备知识之数据绑定 我们可以实现控件属性与自定义对象属性的绑定. 而以上两个功能在实 ...
- WPF中使用MVVM模式进行简单的数据绑定
计划慢慢整理自己在WPF学习和工作应用中的一些心得和想法,先从一个简单的用法说起 在WPF中,XAML标记语言中绑定数据,而数据源就是指定为ViewModel类,而非界面本身的逻辑代码类 这样一定程度 ...
- WPF学习12:基于MVVM Light 制作图形编辑工具(3)
本文是WPF学习11:基于MVVM Light 制作图形编辑工具(2)的后续 这一次的目标是完成 两个任务. 本节完成后的效果: 本文分为三个部分: 1.对之前代码不合理的地方重新设计. 2.图形可选 ...
随机推荐
- python实现接口自动化
一.总述 Postman:功能强大,界面好看响应格式自主选择,缺点支持的协议单一且不能数据分离,比较麻烦的还有不是所有的公司都能上谷歌SoupUI:支持多协议(http\soup\rest等),能实现 ...
- #Virtual hosts #Include conf/extra/httpd-vhosts.conf 开启就不能启动apache
#Virtual hosts#Include conf/extra/httpd-vhosts.conf我只要把其中任何一个开启就是吧#去掉就启动不了apache.怎么回事error.log是这样的ht ...
- Ubuntu16.04 下python2 | python3
在终端分别输入python,python2,python3 python和python2默认都是python2 python3才是python3 Ubuntu下是默认没有pip的,需要自己手动安装 s ...
- HDUJ 1203 I NEED A OFFER!
I NEED A OFFER! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- 嵌入式开发之davinci--- 8148/8168/8127 中的图像处理vpss link dei、sclr、swms、Mosaic’s
vpss 中的link (1)dei dei 主要做数据交错处理,带缩放 dei control data flow: (2)sclr 8168中支持缩放按比例的分子和分母,只支持缩小,貌似不支持放大 ...
- 【iOS系列】-程序开启后台运行
[iOS系列]-程序开启后台运行 iOS程序是伪后台的运行,可是有时候我们需要让其在后台也要进行一些操作,我们可以让其伪装成音乐的APP,这样就可以让程序后台进行相关操作了,具体做法如下: 1:在Ap ...
- Android Studio keymap到Eclipse后,查找下一个同样变量快捷键Ctrl+K失效
注:升级到0.8的版本号以后.这个快捷键能够使了,只是另一个bug,假设你用了Ctrl+F先去查找了其它的东东,再使这个快捷键去定位另外一个变量可能偶尔会不灵,不灵的话还是能够用我以下的方式来让Ctr ...
- [IT学习]跟阿铭学linux(第3版)
1.安装Linux在虚拟化平台上 Windows Vmware Workstation,需要在本机上打开CPU对虚拟化的支持.Virtualization Cent OS7 已成功安装. 2.http ...
- extjs grid 列顺序紊乱问题
这个问题描述类似 关于extjs表格列展示顺序问题 明明在columns定义好了,理应按照里面的顺序输出嘛,但偏不,原本应该列在第一位的,结果忽而在最后,忽而在中间,忽忽何所似,天地一狗屎. 在谷歌里 ...
- 2016/05/11 Thinkphp 3.2.2 验证码 使用 及校验
先新建一个公共控制器,用于放置验证码的实例化代码(不用新建控制器也行,任意公共控制器都可以). 例如:PublicController.class.php 4 5 6 7 8 9 10 11 12 1 ...