XAML将代码数据化

Mon 08 July 2019 / In categories Library

WinRT, XAML

代码数据化或许是一种潮流,越高级的语言作成的代码或许越容易数据化。

从Windows 8开始,Windows开始引入Windows Runtime(简称WinRT,读作winner T)。和传统的基于C语言的Win32 API不同,WinRT基于COM又超出COM,是组件化的API,而不是Win32那种基于函数调用(或者回调)的过程式API。这和C#这种高级语言的流行大有关系。传统的C/C++在支持组件化编程方面存在一定的缺陷,比如需要手动管理内存,以及没有反射,诸如此类的缺点。而C#则是基于CLR,既不需要程序员管理内存,而且还支持反射。而支持反射也就意味着可以避免像C/C++那样,类型定义必须在头文件中定义。C#可以直接从Assembly(也就是一个个DLL)获取类型相关的信息。

从最近C++的发展情况来看,其正在不断向组件化发展,比如C++中已经有对Module的提案。如果该提案工作,则可以在C++中导入Module,而不是包含头文件。Module其就是一个预编译好的代码单元,其原理应该跟预编译头文件差不多。

高级的语言容易数据化。因为如果你仔细看你缩写的程序,无非是一堆数据的堆砌。而每种数据结构的定义,其实嵌套着一层子数据结构的定义,其又继续嵌套其他孙数据结构的定义。从面向对象的角度,一种代码数据结构,其实就是一颗树,每个节点就是一个对象的类型的定义。既然如此,为什么不能够以数据化的方式来描述这颗树呢?比如说天然树形结构的XML,就很适合描述这种代码数据结构。

XAML就采用相同的思路。XAML是WinRT用来描述图形UI的XML定义。先来看一个例子:

<Grid>
    <Grid.Children>
        <TextBlock Text="one" />
        <TextBlock Text="two" />
        <TextBlock Text="three" />
    </Grid.Children>
</Grid>

上面的例子参考自Charles Petzold的Programming Windows, 6th Edition(其示例代码可以在 Examples for Programming Windows 6th Edition获取)。上面的Grid其实是WinRT提供的一个对象,这个对象有一个权属(Property)Children,可以接受其他对象的集合,这里Children权属被赋予三个TextBlock对象的集合,每个TextBlock的权属被赋予不同的值,分别是”one”、“two”和“three”。这样,一个UI对象树就构建起来了。编译以后,会在界面联排显示三段文字,分别是”one”、“two”和“three”。

能够在XAML中使用的对象,必须支持无参数构造,也就是说,单单指定<TextBlock/>,而不指定其Text属性,必须也能工作。

上面例子中的Grid.Children中的Children和TextBlock Text=“one” 中的Text都是对象的权属,只不过采用不同的XML语法来描述。前者以XML元素方式来描述,叫做权属元素(Property Element);后者以XML属性的方式来描述,叫做权属属性(Property Attribute)。

对于权属元素方式,还有更简略的表达方式。如果把Grid的Children权属指定为内容(Content)权属,对于内容权属,默认可以不指定,这样就可以把上面的XML简化成:

<Grid>
    <TextBlock Text="one" />
    <TextBlock Text="two" />
    <TextBlock Text="three" />
</Grid>

注意,为了避免歧义,内容权属必须出现在其他权属后面:

<Grid>
    <Grid.Background>
        <SolidColorBrush Color="Blue" />
    </Grid.Background>
    
    <TextBlock Text="one" />
    <TextBlock Text="two" />
    <TextBlock Text="three" />
</Grid>

XAML作为一种XML文件,需要指定默认的命名空间,这样才知道哪种XML元素是有效的XAML元素。XAML中的默认XML元素都来自于WinRT,其命名空间如下所示:

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
>

XAML的默认命名空间是http://schemas.microsoft.com/winfx/2006/xaml/presentation。这应该是出于历史原因,XAML一开始是给Silverlight(Flash的竞争品)和WPF(Windows Presentation Foundation)使用的。

WinRT提供一套基础的UI控件,采用所谓的Fluent风格。没想到微软竟然将其代码开放了,在Windows UI Library可以查看和获取。WinUI主要是基于C++编写的。

真正在应用程序中使用XAML,其实有两道工序,第一道工序是编译,将XAML中定义的对象实例化以后存储在执行文件中;第二道工序是在程序加载的时候,根据XAML的描述,将对象实例从执行文件中恢复出来,并且组织成树状结构。

到此准备收笔,最后小结一下,将代码数据化的好处是将代码中的逻辑变得更加通用。代码其实用于编译过程的数据,专为编译设计,通用性较差。将代码中的逻辑等同转化为XML这种通用数据类型,使得数据可以被多用工具处理,比如就有专门的可视化工具用来设计XAML界面。所付出的代价是在代码中使用XAML,需要通过一个解析器将XAML进行转化,才能和代码配合操作。

说实话,感觉XAML有点抄袭Apple的Interface Builder,不过需要深入了解才能判断。

(完)

Load Disqus Comments