一、声明式编程
前面学的大多都是命令式或过程式编程,须具体描述某个功能的过程、算法,怎么实现。
命令式编程:命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现。
声明式编程:告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。
简单地说:声明式编程要的是“结果”,命令式编程要的是“过程”
例如:SQL语句就是声明式,它只说明需要的结果,如:表中男性最高成绩的前三名,至于怎么实现,比如怎么过虑男性
怎么排序,怎么取得前三名,它都不关心,它只要结果。
而命令式编程则必须描述怎么过滤男性、怎么排序、怎么取得前三名。
通俗的说,声明式编程更象是一位领导,它只须交待给下属,他要的一个结果,而不去关心怎么去完成的这个过程。
命令式编程更象是一位下属,它得具体去操作每个细节,怎么实现,最后才得出结果。
VB.net是命令式语言,但也包含一些声明式结构。比如Handler子句就是声明式结构。
XAML语言比较接近纯粹的声明式语言,它仅关注结果或当前状态,而不关注如何实现。
为什么要有声明式语言?
用声明式语言能简单地说明要的结果,当这个语言(XAML)传到另一个解读的程序时,它会根据这个结果,来具体实现。
于是就把结果与实现分离。可以想到的是程序的传输体积小了,编程更标准化、更高效,因为结果的实现都是由标准地进行
实现。
文件-》新建项目,选择WPF应用程序,建立ProVB_XAML程序:
界面如上。
窗体的XAML如下:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
</Grid>
</Window>
双击解决方案中Application.xaml,可以看到:
<Application x:Class="Application"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
注意的是下面是一个语句中,后面都是
<Application x:Class="Application"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
xmlns是XML Namespaces的缩写,即XML命名空间。
这四个属性中:xmlns和xmlns:s分别是指的两个命名空间。默认的命名空间是指xmlns所指的内容。
但要用另一个怎么办?用xmlns:x来指明另一个,这样要使用这个命名空间的内容时就可以用前缀x:来指代。
于是没有前缀(省略)的是指第一个,用了x:的是指的是第二个。
它只是定义了应用程序环境,后面几个都是它的结节,最后一个表示下步打开的是MainWindow.xaml文件。
Resource里面描述如何使用XAML声明的对象的属性,如控件的颜色、形状、和行为等。
二、XAML语言基础
前面从感官上认识了声明式编程与XAML,再看看XAML几个重要概念
(具体学习www.w3schools.com)
1、XAML子集
XAML还可以被用于其它平台来表示非.net对象,XAML有以下几个子集:
WPF XAML 描述WPF内容的元素,如矢量图形、控件以及文档。
XPS XAML 是WPF XAML的一部分,为格式化的电子文档定义了一种XML表示方式。(前面说过可以减小传递体积)
Silvelight XAML 用于Silverlight程序的WPF XAML子集(主要用于二维图形、动画音频、视频)
WF XAML 描述Windows工作流(WorkFlow)内容的元素。
2、XAML编译
XML主要用于传递数据,但没压缩。而WPF使用BAML(binary Application Markup Language二进制应用程序标记语言)
它实际上是XAML的二进制表示,更减小了体积。
不必担心如何由XAML转为BAML,编译器会在后台自动执行,当然也可以不编译(比如用户界面须要自定义时)
3、XAML标准
(1)XAML中所有元素都映射为一个.net类的实例。元素的名称也完全对应于类名。
如元素<Button>指示WPF创建一个Button对象。
(2)与XML一样,可在一个元素中嵌套另一个元素。
<Grid>
<Button>
.....
</Button>
</Grid>
(3)可通过特性(Attribute)来设置每个类的属性(Property)。
4、顶级元素(根)
与XML一样,XAML只能使用一个顶级元素:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
</Grid>
</Window>
上面顶级元素就是Window。
顶级元素只能使用下面的:
Window元素
Page元素(与Window元素类似,它仅用于可导航的应用程序)
Application元素(它定义应用程序资源和启动设置)
5、XAML的名称空间
每个元素生成时使用的名称空间是不一样,要引用各个元素的空间显得非常烦扰和混乱,怎么有效的把它们组成到一个统一的
名称空间中来,使得简捷有效呢?
答案是用另外的一个名称空间来包含上面杂乱的空间。于是形成了下面两个统一的空间
XMAL使用两个名称空间:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
(1)http://schemas.microsoft.com/winfx/2006/xaml/presentation
这是WPF的核心名称空间,它包含了所有WPF类,包括用于构建用户界面的控件。它是默认的名称空间,
即省略前缀时,就是指的是这个名称空间
(2)http://schemas.microsoft.com/winfx/2006/xaml
这是XAML名称空间。它包含各种XAML实用特性,这些特性(Attribute)会影响文档的解释方式。
这个名称空间被映射为前缀x,意思是x是一个别名,指代的是这个空间,只要前缀用了x:就说明用的是这个空间。
使用形式如<x:ElementName>
注意:XML名称空间通常用的是URL字符,但这并不是网址,用它可以区别是Microsoft公司而不是其它组织,因为
schemas.com域是由Microsoft公司所拥有的,只有微软会在XML空间名称中使用它。
通过名称空间(命名空间)XAML解析器可以找到正确的类,如查找Window和Grid元素时,会先查默认WPF的名称空间,
再查找.net名称空间,直到找到System.Windows.Window类和System.Windows.Controls.Grid类为止。
6、代码隐藏类
通过XAML就可以构造用户界面,但这就是外观还需要一定的功能,就需要一个连接包含实现代码的方法。怎么实现?
XAML通过使用Class特性来完成:
<Window x:Class="WindowsApplication.Windows1"
Class用了前缀x:,表示是XAML语言中更通用的部分。
Class特性告诉XAML解析器使用指定的名称生成一个新类,该类继承XML元素命名的类。即:
上面创建了一个名为Window1的新类,该类继承自Window基类。
关键:
通过Partial Class部分类,把一个类分成两个或多个,并在编译过的程序集中把这些独立的部分融合成一起,就形成 了
界面与代码的组合。
三、XML语句
XAML名称空间中的3类XML语句:特性、标记扩展、XAML指令
注意:特性(Attribute)与属性(Property)两者相似,但又不同。
1、特性
XML中特性表示与XML节点相关的命名属性。
节点对象可能有几个特性,如Name、Margin、Text,
特性只存在于节点的定义中,不包含在XML的节点中:
x:Class 配置 XAML 编译,在标记和代码隐藏之间连接分部类。代码分部类在一个独立的代码文件中定义,
标记分部类由代码生成过程在 XAML 编译期间创建。
<object x:Class="namespace.classname"...>
...
</object>
x:FieldModifier 修改 XAML 编译行为,使指定对象引用的字段被定义有 public 访问权限而不是默认的 private 行为。
<object x:FieldModifier="public".../>
x:ClassModifier 在同时提供了 x:Class 的情况下,修改 XAML 编译行为。 具体而言,不必创建有 Public 访问级别
(默认值)的 class 分部类,提供的 x:Class 是以 NotPublic 的访问级别创建的。 此行为会影响生成
的程序集中的类的访问级别。
<object x:Class="namespace.classname" x:ClassModifier="NotPublic">
...
</object>
x:Key 唯一标识作为资源被创建和引用的元素,这些资源存在于一个 ResourceDictionary 中。
<ResourceDictionary>
<object x:Key="stringKeyValue".../>
</ResourceDictionary>
x:Name 唯一标识对象元素,可方便从代码隐藏或一般代码中访问已实例化的对象。应用于支持的编程模型之后,
x:Name 可视为等效于持有一个对象引用(由一个构造函数返回)的变量。
<object x:Name="XAMLNameValue".../>
x:Subclass 在同时提供了 x:Class 的情况下,修改 XAML 标记编译行为。 不必根据 x:Class 类创建分部类,而是将
提供的 x:Class 创建为中间类,然后提供的派生类应基于 x:Class。
<object x:Class="namespace.classname" x:Subclass="subclassNamespace.subclassName">
...
</object>
x:Shared 当设置为 false 时,会修改 WPF 资源检索行为,以便特性化资源请求为每个请求创建一个新实例,而不是
所有请求共享同一个实例。
<ResourceDictionary>
<object x:Shared="false".../>
</ResourceDictionary>
x:TypeArguments 将泛型的约束类型参数传递给泛型类型的构造函数。
<object x:TypeArguments="typeString" .../>
2、标记扩展
允许包含格式,体现Extensible Application XML中的Extensible(扩展)
x:Array 在XAML里创建一个数组。使用Array扩展创建数组很容易,但在词法上和其他XAML扩展不同,它不需要使用大括号"{}",
原因在于Array里面含有多个元素。.
<x:Array Type="typeName">
arrayContents
</x:Array>
x:Null 指定 null 作为通过一个 XAML 属性设置的属性的值。
<object property="{x:Null}" .../>
<object>
<object.property>
<x:Null />
</object.property>
</object>
x:Reference 引用在 XAML 标记中其他地方声明的实例。 参考涉及元素的 x:Name。
<object property="{x:Reference instancexName}" .../>
<object>
<object.property>
<x:Reference Name="instancexName"/>
</object.property>
</object>
x:Static 按值引用以符合 公共语言规范 (CLS) 的方式定义的任何静态代码实体。 引用的静态属性可以用来提供在 XAML 中的属性的值。
<object property="{x:Static prefix:typeName.staticMemberName}" .../>
x:Type 提供 CLR Type 对象,该对象是指定的 XAML 类型的基础类型。
<object property="{x:Type prefix:typeNameValue}" .../>
<x:Type TypeName="prefix:typeNameValue"/>
3、XAML指令
XAML一般不支持嵌入其它XML数据或代码,但可以通过两个指令做到:
x:Code 允许在 XAML 生产内放置代码。 这样的代码既可由任何编译 XAML 的 XAML 处理器实现编译,也可以留在 XAML 产品中以备
后用,例如由运行时解释。
<x:Code>
// code instructions, usually enclosed by CDATA...
</x:Code>
x:XData 在 XAML 生产中开启 XML 数据岛的放置。 x:XData 中的 XML 元素不应由 XAML 处理器处理,就像它们属于作用的
默认 XAML 命名空间或任何其他 XAML 命名空间的一部分。 x:XData 可包含任意格式正确的 XML。
<x:XData>
<elementDataRoot>
[elementData]
</elementDataRoot>
</x:XData>