WPF第一天

什么是Xaml

Xaml(Extensible Application Markup Language) 可扩展应用程序标记语言,该语言基于xml实现的进行了相应的扩展。该语言很容易进行扩展,有点类似B/S编程中的代码后置,前端是HTML,后台是业务逻辑和相关处理代码。

还有一点是我们反复强调的,XAML并不是HTML。尽管XAML在元素的声明、程序样式的设置和指定事件处理程序上都和HTML非常类似,但是XAML是基于XML的,它是WPF的外在表现形式。而HTML主是一种标记语言,仅仅是用来为浏览器呈现页面内容。XAML除了用来呈现信息和请求用户输入等基本的功能外,它还包含了一些高级的特性,例如它提供了对动画和3D众多方面的支持。

xaml语言,微软提供了可视化的设计工具blend。基于blend创建的的界面模型及效果,都可以存储或者转换为xaml格式的代码,这样就可以大大的提高了团队中的设计人员和开发人员之间的协作,减少了设计人员原型效果,开发人员无法实现,设计人员可以自行设计后,转换为xaml代码。

关于xaml更多的内容,可以参考维基百科或百度知道。

相关的简单说明如下:

image

对于熟悉XML的同仁,应该没有什么难理解的。

什么是路由事件

我们先来看看MSDN给出的定义:

功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。

实现定义:路由事件是一个 CLR 事件,可以由 RoutedEvent 类的实例提供支持并由 Windows Presentation Foundation (WPF) 事件系统来处理。

我们来解释下MSDN给出的定义:

1、传统方式:

image

对应的xaml代码和后台代码如下:

image

后台对于的处理如下:

image

当然采用如下的方式也是可行的。

image

image

后台代码修改为:

image

2、WPF的路由方式:

路由事件使用以下三个路由策略之一:

冒泡:针对事件源调用事件处理程序。路由事件随后会路由到后续的父元素,直到到达元素树的根。大多数路由事件都使用冒泡路由策略。冒泡路由事件通常用来报告来自不同控件或其他 UI 元素的输入或状态变化。

直接:只有源元素本身才有机会调用处理程序以进行响应。这与 Windows 窗体用于事件的“路由”相似。但是,与标准 CLR 事件不同的是,直接路由事件支持类处理(类处理将在下一节中介绍)而且可以由 EventSetter 和 EventTrigger 使用。

隧道:最初将在元素树的根处调用事件处理程序。随后,路由事件将朝着路由事件的源节点元素(即引发路由事件的元素)方向,沿路由线路传播到后续的子元素。在合成控件的过程中通常会使用或处理隧道路由事件,这样,就可以有意地禁止显示复合部件中的事件,或者将其替换为特定于整个控件的事件。在 WPF 中提供的输入事件通常是以隧道/冒泡对实现的。隧道事件有时又称作 Preview 事件,这是由隧道/冒泡对所使用的命名约定决定的。

在传统的方式中,我们必须对每个事件源进行事件处理绑定,如果我们新增加新的对象或者新的事件源,那么我们还需要添加新的绑定。而这一切在WPF,都被统一处理和考虑了,下面,我们以冒泡为例来简单说明。

image

冒泡的顺序

image

修改后台代码如下:

image

关于逻辑树与可视化树,我们这里解释下:

逻辑树:简单来说,就是我们从界面上来看 界面的可视化基本组成部分,这就构成了窗口的一个逻辑树。逻辑树始终存在于WPF的UI中,不管UI是用XAML编写还是用代码编写。WPF的每个方面(属性、事件、资源等等)都是依赖于逻辑树的

image

可视树:可视树基本上是逻辑树的一种扩展。逻辑树的每个结点都被分解为它们的核心视觉组件。逻辑树的结点对我们而言基本是一个黑盒。而可视树不同,它暴露了视觉的实现细节。下面是Visual Tree结构就表示了上面四行XAML代码的视觉树结构。

image

可视树,将界面组成的所有对象本身的内容进行了解析,例如button 按钮,他的内容,是有contentpresenter和textblock构成。

关于逻辑树和可视树的更多介绍,可参考MSDN的介绍。

我这里给出简单的获取逻辑树和可视树的代码:

image

都上WPF本身提供了一些方法。采用递归的方式。

我们接着上面的关于查看事件源的地方:

image

经过上面我们看到了,默认情况下,WPF的事件是采用冒泡的方式进行事件的传递的,那么我们如何采用其他的二种策略呢?

我们再来看下隧道事件,隧道事件的顺序如下:引用MSDN中的解释图:

输入事件的冒泡和隧道

事件的处理顺序如下所示:

针对根元素处理 PreviewMouseDown(隧道)。

针对中间元素 1 处理 PreviewMouseDown(隧道)。

针对源元素 2 处理 PreviewMouseDown(隧道)。

针对源元素 2 处理 MouseDown(冒泡)。

针对中间元素 1 处理 MouseDown(冒泡)。

针对根元素处理 MouseDown(冒泡)。

我们来验证下,我们以此处理所有的preview事件,看看是不是按照上面介绍的方式去处理的。

image

对应的后台代码如下:

image

运行,后查看输出结果:

image

与我们预期的一致。关于更多的路由事件,我们后面通过单独的章节来说明。

WPF基础控件

系统默认提供的基础控件:

image

image

有些由于自己也没有进行深入的使用,可能就不会介绍太详细。

关于控件的基本使用,会在后续进行深入的讨论和演示。

什么是依赖属性

DependencyProperty(依赖属性):Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展公共语言运行时 (CLR) 属性的功能,这些服务通常统称为 WPF 属性系统。由 WPF 属性系统支持的属性称为依赖项属性。

WPF界面控件中的属性,都可以称作是依赖属性,通过依赖属性,我们能够实现viewModel与界面元素属性之间进行绑定。

依赖属性与我们平时说的属性有区别的。

1、传统的属性

image

这没啥好说的,就是我们针对对象进行了封装。

假设,我们有一个类,有很多的属性,而且,又被多个对象继承,我们知道继承的特性,那么肯定会有很多的属性,本身我们可能基本不适用,那么该属性,还是会被创建的时候实例化,那么有没有什么办法,我们减少这样的开销呢?WPF针对这样的情况提出了依赖属性的概念。

2、依赖属性:

查看其基本的声明和定义:在注释中描述:通过方法设置的属性,数据绑定,动画,样式等。

image

依赖属性就是自己自己没有值,通过Binding从数据源获得值,就是依赖在别人身上,拥有依赖属性的对象称为依赖对象。

我们来看看WPF控件的基本继承链

Object类:在.Net中所有类型的根类型

DispatcherObject类:WPF 中的大多数对象是从 DispatcherObject 派生的,这提供了用于处理并发和线程的基本构造。WPF 基于调度程序实现的消息系统。

DependencyObject类:表示一个参与依赖项属性系统的对象。

Visual类:为 WPF 中的呈现提供支持,其中包括命中测试、坐标转换和边界框计算。

UIElement 类: WPF 核心级实现的基类,该类建立在 Windows Presentation Foundation (WPF) 元素和基本表示特征基础上。

FrameworkElement 类:为 Windows Presentation Foundation (WPF) 元素提供 WPF 框架级属性集、事件集和方法集。此类表示附带的 WPF 框架级实现,它是基于由UIElement定义的 WPF 核心级 API 构建的。

Control类:表示 用户界面 (UI) 元素的基类,这些元素使用 ControlTemplate 来定义其外观。

ContentControl类:表示包含单项内容的控件。

ItemsControl类:表示一个可用于呈现项的集合的控件。

Decorator类:提供在单个子元素(如 Border 或 Viewbox)上或周围应用效果的元素的基类。PPT中鼠标滑过文本框后,出现边框

Image类:表示显示图像的控件。

MediaElement类:表示包含音频和/或视频的控件。自己封装一个视频播放器

Panel类:为所有 Panel 元素提供基类。使用 Panel 元素在 Windows Presentation Foundation (WPF) 应用程序中放置和排列子对象。

Sharp类:为 Ellipse、Polygon 和 Rectangle 之类的形状元素提供基类。

image

关于依赖属性的声明和更详细的内容,我们在后续的单独的章节中有更详尽的介绍。

几种应用依赖属性的场景:

希望可在样式中设置属性。

希望属性支持数据绑定。

希望可使用动态资源引用设置属性。

希望从元素树中的父元素自动继承属性值。

希望属性可进行动画处理。

希望属性系统在属性系统、环境或用户执行的操作或者读取并使用样式更改了属性以前的值时报告。

希望使用已建立的、WPF 进程也使用的元数据约定,例如报告更改属性值时是否要求布局系统重新编写元素的可视化对象。依赖对象创建时并不包含存储数据空间。WPF中必须使用依赖对象作为依赖属性的宿主。

后面的章节,我们会结合具体的案例,来说明如何使用依赖属性。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 目录 什么是WPF? WPF的历史? 为什么要用WPF及WPF作用 WPF与winForm区别? 什么是WPF? ...
    灬52赫兹灬阅读 5,798评论 2 11
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,834评论 25 707
  • 江浩_9835阅读 148评论 0 0