Windows Phone 8初学者开发—第4部分:XAML简介
原文地址:http://channel9.msdn.com/Series/Windows-Phone-8-Development-for-Absolute-Beginners/Part-4-Introduction-to-XAML
系列地址:http://channel9.msdn.com/Series/Windows-Phone-8-Development-for-Absolute-Beginners
源代码: http://aka.ms/absbeginnerdevwp8
PDF版本: http://aka.ms/absbeginnerdevwp8pdf
在本课中,我将讨论在第一课中编写的SoudBoard应用程序的XAML语法。希望您注意到了我们编写的XAML是如何影响手机预览窗格中我们见到的内容。通过查看XAML来理解绝对基本的XAML是相对简单的,但是我想指出一些并非一眼就能看出的特性和功能。
概要地讲本课的计划是:
[*]我们将通过与C#的比较来讨论XAML的目的和性质
[*]我们将讨论XAML的特殊特性,语言的一些隐藏功能,这些功能并非看一眼就显而易见。
我的目标是:当本课结束时您将具备足够的理解我们在本系列其余部分编写的XAML的知识,并且在我试图解释前就能够基本猜出它的作用。
1. XAML是什么?
在上一课我提到XAML的外观与HTML类似。这并非偶然。XAML其实就是XML(可扩展标记语言the eXtensible Markup Language)。我待会儿会解释它们的关系,但是概要地讲,XML和HTML非常相似,它们具有共同的祖先。HTML用于构建web页面文档,而XML则更通用。此处“通用”的意思是您可以针对设想的任意用途来使用它,并且您可以定义元素和特性(attributes)的名称来满足您的需要。过去开发者利用XML来存储应用设置,在两个不同的系统之间传输数据。为了使用XML,您需要定义架构(schema),它对元素和元素特性的名称进行声明。架构类似于一个合约(contract)。每个人,不管他是XML的生产者还是XML的使用者都遵守合约的规定以在相互间进行通讯。因此架构是XML的重要组成部分。请记住上述分析,待会儿我们还会对他进行讨论。
XAML是XML的一种特殊用法。很显然,我们已经看到XAML与定义手机的用户界面有关。所以在这点上感觉它非常像HTML。但是有一个很大的区别,XAML实际上用于创建类的实例和设置属性(properties)的值。例如,在前面的课程中我们在XAML中定义了一个按钮:
上述代码大致等同于以下的C#代码:
我已将上述C#代码添加到MainPage类的构造函数中。我待会儿会讨论MainPage.xaml和MainPage.xaml.cs之间的关系,但是我们已经看到如何在MainPage.xaml.cs中通过编写程序方式的C#代码来定义行为。这里我仅仅编写了在MainPage类的新实例被创建时执行的代码(通过在类的构造函数中编写代码来实现)。
现在我有了两个按钮,一个以声明方式在XAML中定义、含有“内容Hello World”并且在单击按钮时会发出嘎嘎的叫声,另一个是新创建的含有内容“Quack” 的按钮。当我们运行应用:
我们仅能看见一个按钮。那是因为我刚在C#中以程序方式(在MainPage类的构造函数中)创建的按钮位于我们在上一课中在XAML中创建的按钮之上。我将加入一行C#代码用于设置新的Quack按钮的边距(margin),将它移动到靠左210像素的位置。
按钮的边距(Margin)属性是Thickness类型,它是一个通用用途的代表4个维度的类。在这里我们创建了一个新的Thickness类并设置它的构造函数的第一个参数为210像素。当我们再次运行应用:
我们现在可以看到两个按钮。
更大的问题是我们有了两个(几乎)相同的按钮,一个以声明方式在XAML中创建,另一个以程序方式在C#中创建。
当我这样创建一个新的XAML元素时:
我基本上是在创建了一个新的按钮类的实例。
当我设置按钮元素的特性时,我基本上在设置按钮类实例的属性。
重要的是:XAML是创建类的实例和设置对象属性的一种更加简化和简洁的语法。用10行C#代码才能完成的工作只需要一行XAML。(即使在编辑器中我将它分成数行,它仍然比用C#创建对象的方法要简短得多)
此外,使用XAML我可以在手机预览窗格中迅速获得反馈。我立即可以看到更改的影响。在编写程序方式的C#代码时,当需要观察对代码的改动如何工作时我需要运行应用程序。
2. 类型转换器简介
如果您有敏锐的眼光,当遇到HorizontalAlignment特性时,您可能已经注意到XAML和C#版本的差异。如果您尝试:
myButton.HorizontalAlignment = “Left”;
将会产生一个编译错误。XAML分析器将通过值转换器来执行字符串“Left”到枚举值System.Windows.HorizontalAlignment.Left的转换。类型转换器是一个类,它可以将字符串值转换为强类型,Windows 8 API中有若干类型转换器,我们会在这个系列中一直使用它们。在本例中的HorizontalAlignment属性,当被微软的开发人员开发时,在源代码中被一个特殊的特性标记,它指示XAML分析器通过类型转换器方法尝试将字符串“Left”匹配为枚举值System.Windows.HorizontalAlignment.Left。
当您试图拼错“Left”时,看看会发生什么:
您将会收到一个编译错误,因为类型转换器不能找到一个准确的匹配以转换为枚举值System.Windows.HorizontalAlignment.Left。
因此,XAML的第一个特点是:它是一种简洁的创建类的实例的手段。在构建Windows 8应用时,它被用来创建用户界面元素的实例,但是XAML不仅仅是一项用户界面技术,它可以在其他技术中用于其他目的。
3. 理解XMAL命名空间声明
接下来,让我们讨论MainPage.xaml文件顶部的代码,我们在之前一直没有涉及到它。
在文件顶部我们看到以下内容:
当您在查看上述内容时,回忆一下我刚才说的—有关架构属于XML的一部分。如果确实如此,那么XAML在哪里保证遵守架构?
观察第3行至第8行。MainPage.xaml需要保证遵守六个架构。每一个都通过xmlns特性来定义。在第3行定义的第一个xmlns是缺省的命名空间,换句话说没有冒号和冒号后的单词,就像你在第4行至第8行看到的那样。
第4行至第8行的其余命名空间使用名称/冒号的组合。因此,需要说明的是:x 或:phone是与架构(我们将其称为合约)相关的命名空间。MainPage.xaml其余部分的每个元素或特性必须遵守至少这些架构中的一个,否则文档就是无效的。换句话说,如果XAML中的元素或特性没有在这些命名空间中定义,那么就不能保证编译器(即分析源代码并创建可执行文件的程序)在手机上运行,编译器将无法理解如何执行特定的指令。
因此,在本例中:
我们将期望Grid元素和Background特性是缺省架构的一部分,缺省架构对应第3行定义的缺省命名空间。
但是,x:Name是对应第4行定义的x:命名空间的架构的一部分。
我有一个好主意,让我们首先定位到缺省的命名空间以了解更多有关命名空间的构成:
http://schemas.microsoft.com/winfx/2006/xaml/presentation
什么?!架构在该URL实际上并不存在!在这个意义上讲,架构并没有在该URL发布并可以查看。相反,架构只是一个唯一的名称,类似于我们在C#中使用命名空间识别两个具有相同名称的类。架构(因此,在XAML中的命名空间)使得类名称可以被排序,有点类似于姓氏和名字。该URL,或更恰当地说我们应该认为它是URI(Uniform Resource IDENTIFIER 统一资源标示符,而不是Locator 定位器),被用作命名空间的标示符。XML命名空间是对各类应用程序分析XAML的指令。Windows运行时XAML分析器将努力把它变成可执行代码,而Visual Studio和Blend设计器将努力把它变成设计时的体验。
因此,第二个XML命名空间定义了一个映射,x:属于该架构。
http://schemas.microsoft.com/winfx/2006/xaml
因此,任何前面带有x:前缀的元素或特性名称意味着他们遵守第二个架构。
但是区别在哪里?差别很小,但是第二个架构定义了XAML的内在规则。第一个架构定义了Windows 8对XAML特定使用方面的合约/规则。换句话说,我们可以不需要前缀而使用Grid, Button, MediaElement 和其他Windows Phone 8 XAML元素的事实意味着他们定义于缺省的命名空间中。
第5和第6行为Phone(手机)和Shell(界面)定义了命名空间和架构,他们位于不同的URI,注意Microsoft.Phone CLR(是Common Language Runtime的缩写,即通用语言运行时)命名空间提供的线索,定义他们的程序集在安装Windows Phone 8 API后被安装在我们的计算机上。
您可以看到,第一行:
页:
[1]