WPF入门(1)——DataContext
在WPF中,应用程序有两层:UI层和Data层。这里新建一个项目说明哪些是UI层,哪些是数据层。

UI层很明显,就是用户看到的界面。但是数据层并不是下图所示:

上图中是UI层view的后台代码。当然,你可以使用事件的方式把所有的业务逻辑代码写到这里,但是我们采用MVVM的时候业务逻辑是与这里解耦的,数据层是DataContext,此时并没有指定。
接下来我们新建个目录,然后添加个类文件:

然后指定VM类为DataContext:

此时我们才算为MVVM模式的wpf应用程序创建了数据层,也就是MainViewModel类。
默认,应用程序的数据层(DataContext)是null,我们可以使用DataContext属性对其进行设置。
除非另行指定,否则所有UI对象都将从其父对象继承其DataContext。
实际上DataContext才算是我们的实际应用程序(业务逻辑),他通常由ViewModels和Models组成。
UI对象(如按钮,标签,DataGrids甚至Windows)实际作用是允许用户轻松与DataContext交互。
当你写<Label Name="myLabel" Content="{Binding Path=Name}" />你是绑定到myLabel.DataContext.Name,而不是myLabel.Name。
<!-- 注意此时我已经在初始化代码中设置DataContext 为 ClassA,DataContext = new ClassA -->
<Window x:Name="MyWindow">
<!-- DataContext 没有被指定,所以继承自父类
的 DataContext,也就是 ClassA -->
<StackPanel>
<!-- DataContext 继承自父类,也就是
ClassA, 所以这里会显示 ClassA.Name -->
<Label Content="{Binding Name}" />
<!-- DataContext 仍然是ClassA, 但是我们通过binding设置为ClassA.ClassB-->
<StackPanel DataContext="{Binding ClassB}">
<!-- DataContext 继承自父类,也就是ClassB,所以这里会显示 ClassB.Name -->
<Label Content="{Binding Name}" />
<!-- DataContext i仍然是 ClassB, 但是我们binding 到了Window's DataContext.Name, 也就是 ClassA.Name -->
<Label Content="{Binding
ElementName=MyWindow,
Path=DataContext.Name}" />
</StackPanel>
<!-- We've left the StackPanel with its DataContext
bound to ClassB, so this Label's DataContext
is ClassA (inherited from parent StackPanel),
and we are binding to ClassA.ClassB.Name -->
<Label Content="{Binding ClassB.Name}" />
</StackPanel>
</Window>
所有基本绑定都在UI对象的数据层(DataContext)中寻找它们的值。
综上所述,WPF应用程序具有两层:UI层和数据层。应用程序的数据层以null开头,可以使用DataContext属性设置。未设置DataContext的UI对象将从其父对象继承其数据层。绑定用于在数据层中查找值,并在UI层中显示它们。
使用MVVM设计模式时,数据层是您的应用程序,而UI层只是提供了一种用户友好的方式来访问数据层。
datacontext的绑定
可以在view的后台代码中手动指定例如在构造函数中:
var cont = new MainViewModle();
DataContext = cont;
另外也可以写到资源中,首先需要写一个viewmodel类:
public MainViewModel()
{
plusCommand = new PlusCommand(this);
}
然后把vm类放到资源中:
<!--需要指定名称空间vm:
xmlns:vm="clr-namespace:SimpleCommandDemoApp.ViewModels"-->
<UserControl.Resources>
<vm:CalculatorViewModel x:Key="calculatorVM" />
</UserControl.Resources>
最后就可以在xaml中指定了:
DataContext="{Binding Source={StaticResource calculatorVM}}"
WPF使用DataContext将数据层与UI层实现了解耦,那么他们之间是如何交互的?实际上上面已经略有涉猎,那就是Binding,上面实例的ClassA、ClassB的Name就是通过Binding来展示到UI上的,详细介绍在下一篇文章中再做说明。
工程源代码上传在GitHub上了:https://github.com/feipeng8848/WPF-Demo
参考:https://rachel53461.wordpress.com/2012/07/14/what-is-this-datacontext-you-speak-of/
WPF入门(1)——DataContext的更多相关文章
- WPF入门:数据绑定
上一篇我们将XAML大概做了个了解 ,这篇将继续学习WPF数据绑定的相关内容 数据源与控件的Binding Binding作为数据传送UI的通道,通过INotityPropertyChanged接口的 ...
- WPF入门教程系列(二) 深入剖析WPF Binding的使用方法
WPF入门教程系列(二) 深入剖析WPF Binding的使用方法 同一个对象(特指System.Windows.DependencyObject的子类)的同一种属性(特指DependencyProp ...
- WPF入门教程系列(一) 创建你的第一个WPF项目
WPF入门教程系列(一) 创建你的第一个WPF项目 WPF基础知识 快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识: 1) C#基础语法知 ...
- WPF入门教程系列二十三——DataGrid示例(三)
DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...
- WPF入门教程系列十八——WPF中的数据绑定(四)
六.排序 如果想以特定的方式对数据进行排序,可以绑定到 CollectionViewSource,而不是直接绑定到 ObjectDataProvider.CollectionViewSource 则会 ...
- WPF入门教程系列三——Application介绍(续)
接上文WPF入门教程系列二——Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...
- WPF入门教程系列二——Application介绍
一.Application介绍 WPF和WinForm 很相似, WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只 ...
- WPF入门教程系列一
WPF入门教程 一. 前言 公司项目基于WPF开发,最近项目上线有点空闲时间写一篇基于wpf的基础教材,WPF也是近期才接触,学习WPF也是在网上查资料与微软的MSDN进行学习,写本博客的目为了温 ...
- WPF入门(四)->线形区域Path内容填充之填充图(ImageBrush)
原文:WPF入门(四)->线形区域Path内容填充之填充图(ImageBrush) 前面我们提到了LinearGradientBrush可以用来画渐变填充图,那么我们同时也可以使用ImageBr ...
- WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush)
原文:WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush) 前面我们介绍到,Path对象表示一个用直线或者曲线连接的图形,我们可以使用Path.Data ...
随机推荐
- Java并发指南5:JMM中的final关键字解析
本文转载自互联网,侵删 与前面介绍的锁和volatile相比较,对final域的读和写更像是普通的变量访问.对于final域,编译器和处理器要遵守两个重排序规则: 在构造函数内对一个final域的 ...
- spring中文参考指南
主要是4.x版本的 比较全面的:https://muyinchen.gitbooks.io/spring-framework-5-0-0-m3/content/3.5-bean/3.5.4-reque ...
- hive进阶 技巧
1.日期格式转换(将yyyymmdd转换为yyyy-mm-dd) select from_unixtime(unix_timestamp('20180905','yyyymmdd'),'yyyy-mm ...
- About Xi’an
Introduction Ancient Capital It is the birthplace of the Chinese Nation, is one of the four ancient ...
- vue 组件之间通信
父传子 **父组件代码** <template> <header-box :title-txt="showTitleTxt"></header-box ...
- VBA添加下拉菜单
Sub createMenus() Dim cmdBar As CommandBar Dim cmdMenu As CommandBarPopup Dim cmdBtn As CommandBarBu ...
- oracle相关知识点
oracle数据库,实例名和数据库是一一对应的,oracle服务端可以启动多个实例,对应于多个数据库. 数据库可以通过sqlplus / as sysdba 进入默认SID的实例, 查看当前的实例名: ...
- 停止monkey的方法
注意 Monkey启动后会不断地向被测对象发送随机事件流,直到事件执行完毕或者发生异常时才停止.在Monkey运行过程中,即便断开 与PC的连接,Monkey依然可以在手机上继续运行. 停止Monke ...
- 值得学习的C语言开源项目和库
收集一些C/C++相关的源码,如有更高效的库,请提醒我 补充上去 C/C++相关交流Q群 1414577 - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具. ...
- [转]将西部数据 My Passport Wireless 移动存储连接到任何支持的云存储上
原文标题:对西部数据 My Passport Wireless 移动存储进行 Linux 魔改 原文链接:https://linux.cn/article-8246-1.html 虽然 WD My P ...