WPF XAML 从零开始认识XAML

剖析最简单的XMAL代码:

<Window x:Class="MyFirstApplication.MainWindow"xmlns=""xmlns:x=""Title="MainWindow" Height="350" Width="525"><Grid></Grid></Window> 花花绿绿一大片,还有两个像主页地址的东西….它们都是些什么呢,让我们一个个来分析。

XAML是由XML派生出来的语言,所以有很多在XML中的概念在XAML中是通用的。比如使用标签声明一个元素(每一个元素对应内存中的一个对象)时,需要使用起始标签<tab>和结束标签</tag>,夹在起始标签和终止标签中的XAML代码表示隶属于这个标签的内容。如果没有什么内容隶属于这个标签,则这个标签称为空标签,可以写为<tag/>。

为了表示同类标签中的某个标签的与众不同,可以给它的特征(Attribute)赋值。为特征赋值的语法如下: 非空标签:<tag Attribute1=value1 Attribute2=value2>content</tag> 空标签<tag Attribute1=value1 Attribute2=value2/>

在这里有必要把Attribute和Property仔细地辨别一下。

这个词的混淆由来已久,混淆的主要原因是大多数的中文译文里即把Attribute译为“属性”,也把Property译为“属性”,其实,这两个词表示的不是同一个层面上的东西。

Property属于面向对象的范畴。在使用面向对象编程的时候,常常需要对客观事物进行抽象,在把抽象出来的结果封装成类,类中用来表示事物状态的成员就是Property。比如要编写一个模拟赛车的游戏,那么必不可少的就是要对现实的赛车进行抽象,现实中汽车会带很多数据,但是游戏中可能只关心它的长度,宽度,高度,重量,速度等有限的几个数据,同时,还会把汽车的加速,减速等行为提取出来用算法进行模拟,这个过程就是属于抽象(结果是Car这个类)。显然,Car.Length,Car.Height,Car.Weight等表达的是当前汽车所处的一个状态,而Car.Accelerate()、Car.Break()表达的是汽车能做什么。因此,Car.Length,Car.Height就是Property的典型属性,是针对对象而言的。将Property译为“属性”也很贴切,总之一句话:Property属性是针对对象而言的。

Attribute则是编程语言文法层面的东西。比如有两个同类语法的元素A和B,为了表示A与B不完全相同或者A与B的用法上有些区别,这时候就要针对A和B加一些Attribute。也就是说Attribute只与语言层面上的东西有关,与抽象出来的对象没有什么关系。因为Attribute是为了表示“区分”的。所以它译为“特征”。C#中的Attribute就是这种应用的典型例子,我们可以为一个类添加Attribute,这个类里面有很多Property(属性)。显然,Attribute只用来影响类中程序中的用法,而Property 则对应着抽象对象身上的性状,根本不是一个层面上的东西。

习惯上,英语中把标签式语言中表示一个标签特征的“名—-值”对称做Attribute。如果恰好有在使用一种标签式语言做面向对象编程,这两个概念就有可能混在一起了。实际上,使用能够使用面向对象编程的标签式语言只是把标签和对象做了一个映射—–针对标签还是叫做Attribute,针对对象还是叫做Property,仍然不是一个层面上的东西。而且,标签的Attribute不是和对象的Property一一映射的,往往一个标签对于的Atrribute大于他所映射对象的Property。

因为XAML是用来在UI上绘制控件的,而控件本身就是面向对象的抽象产物,所以XAML标签中的Atrribute有一大部分和它对应他的对象的Property是一一对应的。当然,这还意味着标签中的Atrribute并不对应它所代表对象的Property。

明白了XAML的格式以及Atrribute和Property之间对应的关系,对上面的代码可谓是一目了然。它的总体结构是一个Window标签内包含一个Grid标签(或者说Grid标签是Window标签的内容),所代表的内容是一个Window对象里面包含一个Grid对象。

XAML是一种声明式语言,当你看见一个标签,就证明你声明了一个对象,对象之间的关系要么是并列,包含全都体现在标签的关系上。下面的代码就是<Window>标签的Atrribute。

x:Class="MyFirstApplication.MainWindowxmlns="xmlns:x="Title="MainWindow" Height="350" Width="525" 其中Title、Width、Height一看就知道和Window的Property对象对应的。中间两行(即两个xmlns)是在声明名称空间。最上面一行是在使用名为class的Attribute,这个Attribute来自于X:前缀所对应的名称空间。下面仔细解释。

前面已经说过,XMAL语言是从XML语言派生而来的。XML有一个功能就是可以在XML文档的标签内使用xmlns特征来定义名称空间(NameSpace),XML也就是XML–NameSpace的缩写。定义名称空间的好处就是,当来源不同的类重名时,可以使用名称空间加以区分。xmlns特征的语法如下:

xmlns[:可选的映射前缀]=“名称空间” xmlns后可以跟一个可选的映射前缀,之间用冒号隔开。如果没有写可选映射的前缀,那就意味着所有来自这个名称空间的所有标签都不用加这个前缀,这个没有映射的命名空间称为“默认的命名空间”,默认名称空间只能有一个,而且应该选择其中使用最频繁的名称空间来作为默认命名空间。在上面的例子中,<Window>和<Grid>来自于第二行声明的默认命名空间,而第一样的CLASS特征则来来自于三行的中x:前缀对应的名称空间。这里可以做一个有趣的小实验:如果给第二行声明的名称空间加一个前缀,例如n,那么代码必须要改成一下形式编译才能通过:<n:Window x:Class="WpfApplication2.Window2"xmlns:n=""xmlns:x=""Title="Window2" Height="300" Width="300"><n:Grid></n:Grid> </n:Window> XAML中引用外来程序集和其中.NET名称空间的语法和C#是不一样的。在C#中,如果想使用System.Windows.Control名称空间内的Button类,需要先把包含System.Windows.Control名称空间的程序集PresentationFramework.dll添加引用到项目中,然后再用C#代码顶部写上一句:using System.Windows.Control;。在XAML中做同样的事情也需要添加对程序集的引用,然后再在根元素的起始标签中写上一句:xmlns:c="clr-namespace:System.Windows.Control;assembly=PresentationFramework"。c是映射的前缀,换成其它字符串也可以。因为button来自前缀为c的命名空间,所以在使用button的时候就要使用<c:Button>….</c:Button>。蚁穴虽小,溃之千里。

WPF XAML 从零开始认识XAML

相关文章:

你感兴趣的文章:

标签云: