在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的更多相关文章

  1. WPF入门:数据绑定

    上一篇我们将XAML大概做了个了解 ,这篇将继续学习WPF数据绑定的相关内容 数据源与控件的Binding Binding作为数据传送UI的通道,通过INotityPropertyChanged接口的 ...

  2. WPF入门教程系列(二) 深入剖析WPF Binding的使用方法

    WPF入门教程系列(二) 深入剖析WPF Binding的使用方法 同一个对象(特指System.Windows.DependencyObject的子类)的同一种属性(特指DependencyProp ...

  3. WPF入门教程系列(一) 创建你的第一个WPF项目

    WPF入门教程系列(一) 创建你的第一个WPF项目 WPF基础知识 快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识: 1) C#基础语法知 ...

  4. WPF入门教程系列二十三——DataGrid示例(三)

    DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...

  5. WPF入门教程系列十八——WPF中的数据绑定(四)

    六.排序 如果想以特定的方式对数据进行排序,可以绑定到 CollectionViewSource,而不是直接绑定到 ObjectDataProvider.CollectionViewSource 则会 ...

  6. WPF入门教程系列三——Application介绍(续)

    接上文WPF入门教程系列二——Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...

  7. WPF入门教程系列二——Application介绍

    一.Application介绍 WPF和WinForm 很相似, WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只 ...

  8. WPF入门教程系列一

    WPF入门教程 一.  前言  公司项目基于WPF开发,最近项目上线有点空闲时间写一篇基于wpf的基础教材,WPF也是近期才接触,学习WPF也是在网上查资料与微软的MSDN进行学习,写本博客的目为了温 ...

  9. WPF入门(四)->线形区域Path内容填充之填充图(ImageBrush)

    原文:WPF入门(四)->线形区域Path内容填充之填充图(ImageBrush) 前面我们提到了LinearGradientBrush可以用来画渐变填充图,那么我们同时也可以使用ImageBr ...

  10. WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush)

    原文:WPF入门(四)->线形区域Path内容填充之渐变色(LinearGradientBrush) 前面我们介绍到,Path对象表示一个用直线或者曲线连接的图形,我们可以使用Path.Data ...

随机推荐

  1. JavaWeb_(SpringMVC框架)SpringMVC&Spring&MyBatis整合

    JavaWeb_(SpringMVC框架)测试SpringMVC&Spring&MyBatis三大整合 传送门 1.整合ssm 3大框架 过程 a)导包 -> spring_Ja ...

  2. Robot Framework(十九) 附录

    6附录 6.1测试数据中的所有可用设置 6.1.1设置表 Setting表用于导入测试库,资源文件和变量文件,以及定义测试套件和测试用例的元数据.它可以包含在测试用例文件和资源文件中.请注意,在资源文 ...

  3. Maven:禁止编码指定类型的资源文件

    [参考文章]:项目编译后dll文件调用出错 maven 在编译或项目时,可能会对资源文件进二次编码(编译前后的文件大小对比即可发现该问题),有些文件(例如:文本文件)可能不会影响我们是用,但是有些文件 ...

  4. iOS App的几种安全防范

    虽然公司的项目目前还不算健壮,安全问题对于大部分小公司来说似乎并没什么必要,不过要攻击的话,我有十足的把握,我们是无法承受冲击的.嘿嘿嘿~不过带着一颗入坑iOS的心思,搜集了一下资料后,还是做了一些尝 ...

  5. unigui图形验证码

    unigui图形验证码 procedure TMainForm.UniButton1Click(Sender: TObject); var url: SockString; serial: TynSe ...

  6. Linux ubuntu centos 下 grep显示前后几行信息

    标准unix/linux下的grep通过下面参数控制上下文 grep -C 5 foo file 显示file文件里匹配foo字串那行以及上下5行grep -B 5 foo file 显示foo及前5 ...

  7. Mysql触发器详解以及union的使用

    ---恢复内容开始--- Mysql触发器定义: 当一个表中有insert update delete事件发生,触发一个事件,执行一段代码.作用: 同步数据创建: create trigger 名称 ...

  8. Xshell查看日志

    查询日志命令(复制后鼠标右键粘贴): tail  -1000f /mnt/logs/SMFManagement/SMFManagement_info.log

  9. 【NetDevops】网络自动化运维--1获取用户基本信息

     版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.  之前博客的云主机到期了没续费,被删啦最重要的是没有备份!此处省略几个字.....      ...

  10. kotlin标准委托之阻止属性的赋值操作

    import kotlin.properties.Delegates fun main(arg: Array<String>) { val user = user() user.name= ...