在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. zabbix监控项整理Items-key

    agent.hostname:hostname,字符串 agent.ping:可用性检查,可用返回1:不可用返回空 agent.version:agent程序的版本,返回字符串 kernel.maxf ...

  2. 记录学习Linux遇到的问题

    shl@shl-tx:~$ ifconfig Command 'ifconfig' not found, but can be installed with: sudo apt install net ...

  3. ubuntu 上开发.netcore

    ubuntu需要安装的软件: 1.sudo apt-get install openssh-server openssh-client 2.sudo apt-get git 3.安装vscode 4. ...

  4. PLSQL 经常自动断开失去连接的解决过程

    转: PLSQL 经常自动断开失去连接的解决过程 问题背景: 情况是这样的,很多开发同事的PLSQL上班时间开着8个小时,有时候他们出去抽烟后或者中午吃完饭,回来在PLSQL上面执行就报错无响应,然后 ...

  5. Cinder LVM Oversubscription in thin provisioning

    目录 文章目录 目录 Oversubscription in thin provisioning Oversubscription in thin provisioning Cinder spec: ...

  6. JVM-类加载子系统

    类的生命周期 1.加载 将.class二进制字节流流从磁盘读到内存中(通过文件的全限定名读取) 2.连接 2.1验证:验证字节码文件的正确性 2.2准备:给类的静态变量分配内存,并赋予默认值(比如 i ...

  7. 为Django添加图片验证码

    可直接复制到Django项目中使用 # author:sunshine from django.http import HttpResponse from PIL import Image, Imag ...

  8. Android之view的工作原理2

    学习内容 View的底层工作原理,比如View的测量流程.布局流程以及绘制流程:以及常见的View回调方法:熟悉掌握前面的知识后,自定义View的时候也会更加的得心应手. 4.1 初识ViewRoot ...

  9. vim复制粘贴导致多行出现#号解决办法

    在vim内复制多行假如复制的行带有#号会导致其他不带#号的行自动加# 解决办法,输入一下命令再粘贴即可 :set paste

  10. (转)svn执行clean up命令时报错“Previous operation has not finished; run 'cleanup' if it was interrupted”

    今天碰到了个郁闷的问题,svn执行clean up命令时报错“Previous operation has not finished; run 'cleanup' if it was interrup ...