[Windows 8][Metro Style Apps] 淺述XAML

要開發Metro Style Apps所能使用的使用者介面描述語言除了HTML/CSS之外,就只能使用XAML了。所以,對C/C++和.Net Framework平台的開發者來說,好好的來認識一下XAML 就是很重要的一件事囉!!

前言

[Windows 8][Metro Style Apps]Windows 8 開發/執行環境概觀文中的Windows 8的開發/執行平台圖裡,我們可以很清楚的看到,要開發Metro Style Apps所能使用的使用者介面描述語言除了HTML/CSS之外,就只能使用XAML了。所以,對C/C++和.Net Framework平台的開發者來說,好好的來認識一下XAML 就是很重要的一件事囉!!

 

XAML?

XAML的全名為Extensible Application Markup Language,原為WPF(Windows Presentation Framework)的一部份,是一種基於XML衍生而出的宣告式使用者介面描述語言,外觀與HTML相似,平台會自動透過.Net Framework中的反射(Reflection)機制,將XAML中描述的物件,轉換為平台上使用的語言宣告、定義,以方便在之後供Code-Behind的程式碼使用或是進行互動。

如果已經接觸過WPF、Silverlight和Windows Phone開發的朋友們應該就會對下面的XAML Code不陌生:


<Button Name="btnTest">Click Me!!</Button>

透過上面的XAML Code,我們就可以輕鬆的定義出一個按鈕。

 

XML命名空間

而在XAML裡面,我們常常會看到xmlns這個關鍵字,它就類似於C#中的using和VB.Net裡面的Imports關鍵字一樣,代表的是我們要引用的XML命名空間,讓我們可以透過指定xmlns的方式,來引用一些既有的元件、類別或是控制項。

例如,我們有可能看到如下的XAML Code作為整個XAML檔的開頭:


<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppBarControl"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008">

如上例,xmlns冒號(:)後面接的是我們幫該XML命名空間取的別名,而等號(=)後面則是要參考的元件的命名空間路徑或是位置。有些命名空間的位置會以一個看來像是網址的路徑來表示,那個是因為XML命名空間和真正的元件命名空間是以一對多的關係互相對應,而通常就是會以這種類似網址的形式來封裝、映射多個元件命名空間,並不代表該網址真正存在喔!

 

而上例的第一行:


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

並未指定任何的別名,因此它會被當作預設使用的XML命名空間,預設的XML命名空間可以讓我們不用透過指定別名的方式,就可以使用該命名空間裡面的類別或是控制項(例如前面舉的Button的例子,就是因為Button這個控制項已經被包含在該XML命名空間裡了,所以可以直接使用)。而且,通常一個XAML檔中,只能允許一個預設的XML命名空間存在,如果有一個以上的命名空間沒有被賦與別名的話,可是會出錯的喔!!

 

相對的,我們在上面的例子引用了AppBarControl這個命名空間,而且將它的別名取為local,所以我們就可以透過指定特定命名空間的方式,在後面的XAML中使用該命名空間裡面的控制項或是類別,例如:


<local:Page1/>
<local:Page2/>

順帶一提,在WPF和Silverlight中,我們可以透過XmlAttributeProperties.XmlnsDefinition 附加屬性在AssemblyInfo.cs檔中把多個Namespace整合在一起,寫法如下:


[assembly: XmlnsDefinition( "http://Ouch1978.Com/Components" , "Ouch1978.Component1" )] 
[assembly: XmlnsDefinition( "http://Ouch1978.Com/Components" , "Ouch1978.Component2" )] 
[assembly: XmlnsDefinition( "http://Ouch1978.Com/Components" , "Ouch1978.Component3" )]

不過,要注意的是:這個方法在Metro Style Apps中並不支援(喂~那拿出來講幹嘛!?)

 

Reflection與InitializeComponent()方法

前面有提到,XAML會透過Reflection機制,讓我們可以在Code-Behind透過程式碼和XAML Code中描述的物件進行互動,那麼,這個是怎麼完成的呢?我們就跳過複雜的原理解釋,簡單的來看一下我們的Code-Behind程式碼為什麼可以和XAML Code進行互動吧~

我以一個簡單的頁面為例,如下圖:

image

該頁面的XAML Code如下:

BlankPage.xaml

<Page
    x:Class="BlankApplication.BlankPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:BlankApplication"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
        <Button Name="btnTest" Content="Button" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Center" Margin="0,150,0,0"/>
    </Grid>
</Page>

我對Button控制項給了Name屬性,而TextBlock則沒有。再來,我們來看看Code-Behind,如果有安裝Windows 8和Visual Studio 11的朋友也不妨跟著動手試看看:

打開Code-Behind的BlankPage.xaml.cs檔,我們可以看到預設的建構子裡面呼叫了一個名為InitializeComponent()的方法。

image

在該方法上按下滑鼠右鍵,並在彈出的選單中選取Go To Definition(或直接按下F12鍵)。

image

就會看到另一個以Partial Class技術實作的檔案(BlankPage.g.i.cs)跑了出來,而且裡面自動的將有被命名的控制項都以程式碼的方式重新宣告了一次。另外,裡面也以程式碼的方式,再次的指定了描述UI的XAML檔路徑。

image

這個Partial Class是自動產生的,而XAML Code就是透過這個機制來讓Code-Behind存取的喔~~

 

希望經過以上簡單的介紹,能幫助大家對XAML有基本的認識,也能降低對XAML的恐懼感,其實它一點都不恐怖,對吧!?