上一篇曾提及XAML中,每個對象元素的聲明是對.NET類進行一次實例化操作。XAML作為聲明類語言,如何識別對象元素,並如何在.NET Framework中找到對應映射類呢?本篇將引入命名空間(NameSpace)的概念,涉及內容如下:
- NameSpace命名空間格式
- 核心NameSpace命名空間
- 設計類NameSpace命名空間
- 自定義NameSpace命名空間
- XAML命名空間的x:Class屬性
- XAML命名空間的x:Name屬性和x:Key屬性
- XAML的x:ClassModifier屬性和x:FieldModifier屬性
- Silverlight命名空間和Windows 8命名空間的不同
XAML命名空間的概念和C#代碼中的Using,VB.Net代碼中的Import相似,其作用是為對象元素的實例化提供引用類庫聲明。
簡單的理解,當在XAML頁面中需要調用某控件對象時,需要提前對該控件對象的類庫進行引用聲明,而定義XAML命名空間是類庫引用聲明的一種方法。
本篇將使用Visual Studio 11創建一個簡單的Silverlight 5項目,通過對比Windows 8和Silverlight項目的命名空間,幫助理解命名空間的使用。
項目名:XamlGuideSL
Visual Studio 11生成的Silverlight 5默認命名空間代碼如下:
對比上一篇Windows 8實例的命名空間代碼:
通過比較以上兩個命名空間定義,我們可以發現Windows 8和Silverlight 5具有類似的命名空間,例如:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc= http://schemas.openxmlformats.org/markup-compatibility/2006
在移植Silverlight項目到Windows 8平台過程中,WinRT XAML可以兼容Silverlight XAML代碼,輕松實現應用平台移植。
NameSpace命名空間格式
在以上代碼中<UserControl>或<Page>作為頁面Root對象元素被聲明,其開始標簽<UserControl>或<Page>中,包含了多個“xmlns”特性,在XAML語法規則中,“xmlns”是屬於強制關鍵字,被用來聲明一個命名空間。其語法結構為“xmlns:”+“命名空間前綴名”,而對於默認命名空間,無需定義命名空間前綴名。

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
以上四個命名空間是Visual Studio 11創建默認項目時自動生成的,其中分別映射了實例化一個Silverlight或Windows 8空白頁面所需要的公共類庫。
核心NameSpace命名空間
在以上四個命名空間中,“xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"”和“xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"”是一個XAML頁面的核心命名空間,
對於這兩個命名空間的詳細解釋如下:
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"是默認命名空間,其中包含Silverlight或Windows 8核心類,提供兩者基礎應用元素支持,作為核心類庫命名空間,無需定義命名空間前綴名,該命名空間默認作用於整個頁面,從上述代碼中可以看出<UserControl>,<Page>都屬於該命名空間下的元素對象。作為默認命名空間,直接映射多個.Net Framework核心類庫,例如,System.Windows, System.Windows.UIElements, System.Windows.Controls 等類庫。
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"引用默認XAML類庫,其中包含大量XAML語言通用功能類,其作用對頁面XAML提供基礎以及擴展功能支持。這個命名空間使用“x”作為前綴名,表示在XAML頁面中可以使用“x:”引用該類庫。其常用語法結構如下:<x:元素名 />。例如: <Grid x:Name=“LayoutRoot”/>
一個完整的XAML頁面必須具備以上兩個命名空間,否則將無法正常實例化。
設計類NameSpace命名空間
-
xmlns:d=http://schemas.microsoft.com/expression/blend/2008,該命名空間引用Expression Blend輔助設計類庫,對Visual Studio和Expression Blend視圖設計模式提供支持,其實際設計中主要提供設計視圖頁面尺寸定制。
-
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006",該命名空間引用XAML語言輔助類庫,對XAML提供輔助設計支持,主要功能是為XAML語法解析器提供輔助解釋功能,例如,使用mc:Ignorable=“d”告知XAML解析器以“xmlns:d”為前綴的元素引用在運行時被忽略。從前文代碼中可以看到,xmlns:d命名空間前綴名,使用Expression Blend輔助設計類庫中的DesignHeight和DesignWidth,分別定義在設計工具下視圖模式中頁面顯示尺寸,d:DesignHeight="300" d:DesignWidth="400"。正常來說,XAML語法解析器無法識別DesignHeight和DesignWidth,xmlns:mc命名空間則提供Ignorable標識在運行時忽略該引用聲明,避免了在編譯時XAML語法報錯。
自定義NameSpace命名空間
在實際項目中,經常會遇到調用自定義控件類庫,其調用方法可以從默認XAML命名空間聲明轉換得來。
例如,如果需要添加DataGrid數據控件到XamlGuideSL項目中,首先需要添加System.Windows.Controls.Data.dll引用文件到Silverlight項目引用文件目錄,

然后在頁面頭部聲明DataGrid控件所需要的命名空間,XAML頁面才能在.Net Framework中初始化該控件。
從上圖可以看出,添加命名空間引用時,Visual Studio 11自動智能感知,查詢當前引用類庫列表中所有可用引用,選擇“System.Windows.Controls”,代碼將自動填充到XAML頁面。

自定義聲明一個命名空間:xmlns:datagrid="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"這段代碼中包含三部分的信息:
- “xmlns:datagrid”命名空間前綴名,這個前綴名可以由開發人員自定義,但是必須由“xmlns:”作為起始,也就是說,datagrid可以被任何字符替換。根據開發命名標准,推薦開發人員使用簡單的控件名表示,提高代碼可讀性;
- “clr-namespace:System.Windows.Controls”表示該命名空間將映射到System.Windows.Controls 公共語言運行環境命名空間類;
- “assembly=System.Windows.Controls.Data"”表示DataGrid隸屬於System.Windows.Controls.Data.dll動態連接庫中,在編譯時,該DLL文件將被封裝到XAP壓縮文件包中。
完成聲明后,調用方法如下:
<datagrid:DataGrid />
在本篇實例中,使用Expression Blend生成Sample DataSource,綁定到DataGrid控件作為演示(具體步驟這里不再重復,可參考:Expression Blend實例中文教程(6) - 項目控件和用戶交互控件快速入門),最終調用和顯示效果如下:
XAML命名空間的x:Class屬性
Silverlight和基於C#,VB.NET的Windows 8 Metro應用是用戶界面代碼和后台邏輯代碼分離的。其中XAML代碼用於繪制用戶界面,后台邏輯代碼可由開發人員喜好選擇C#或者Visual Basic。XAML既然繼承自XML,也就是說, 其本身不具備事件控制的代碼特性。而為了使XAML能夠實現與后台邏輯代碼交互,則需要在XAML頁面代碼開始時聲明x:Class屬性,使其賦值當前頁面對應后台頁面命名空間,Runtime語法解析器將根據x:Class提供的頁面命名空間名自動創建一個類,該類繼承自x:Class屬性隸屬對象元素。完成類創建后,將判斷是否該頁面是否具有同名后台代碼類,如果有,將合並當前生成類到后台代碼類中。XAML的x:Class屬性只能在頁面的根元素中聲明一次,表示在頁面創建時,保證其包含的所有元素對象僅能被實例化一次。其聲明語法格式如下:
<元素對象 x:Class=“命名空間.調用類名;assembly=程序集名稱”…>
</元素對象>
下面我們嘗試從實例中理解x:Class屬性,在XamlGuideSL項目中,<UserControl>定義x:Class="XamlGuideSL.MainPage", 其含義是該XAML頁面繼承自UserControl對象元素,其對應的后台代碼頁面為“XamlGuideSL.MainPage.cs”,XAML語法解析器將自動檢測並且鏈接該XAML頁面到“XamlGuideSL.MainPage.MainPage.cs”,在XAML實例化時,將執行“XamlGuideSL.MainPage.cs”后台代碼中的構造函數。

從Visual Studio 11默認生成后台代碼中可以看出當前頁面命名空間是“XamlGuideSL”,Mainpage類繼承自UserControl。在構造函數MainPage()中,將執行InitializeComponent()方法,對XAML頁面對象元素進行屬性設置,數據綁定以及聲明事件等操作。由此可見,InitializeComponent()方法在Silverlight應用初始化時具有非常重要的作用,不能從構造函數中刪除。而在創建新的構造函數時,也必須調用該方法,對XAML對象元素進行實例化操作。
XAML命名空間的x:Name屬性和x:Key屬性
在XAML代碼設計時,經常需要對控件或者資源進行命名,所需要使用的屬性是x:Name和x:Key。下面的表格對兩者使用范圍進行對比和描述:

在實際項目中,控件元素和資源的命名規則是只在需要的時候對控件和資源進行命名操作,這樣的好處有以下幾點:
- 減小XAP文件或應用尺寸,加快InitializeComponent初始化調用速度;
- 易於項目維護;
XAML的x:ClassModifier屬性和x:FieldModifier屬性
x:ClassModifier屬性和x:FieldModifier屬性主要功能是支持在XAML中設置后台對應代碼類存取屬性.
x:ClassModifier屬性僅能被用於根元素對象,例如,<UserControl>;
x:FieldModifier屬性僅能被用於控件元素對象,例如,<TextBox>;
在XAML代碼中使用x:ClassModifier屬性和x:FieldModifier屬性后,客戶端編譯后,會在.g.cs或者.g.vb自動生成代碼中重新設置類存取屬性。這里需要注意,對於x:ClassModifier根元素對象類存取屬性的控制,在XAML代碼中修改后,必須同時手工修改對應后台代碼中對應元素對象類的存取屬性。例如:在下面代碼中修改UserControl類存取屬性為internal,

同時也需要修改對應后台代碼XamlGuideSL.MainPage類的存取屬性,Visual Studio 11默認創建屬性為Public,

查看.g.cs自動生成代碼,
MainPage的類存取屬性被編譯為internal。
由此,x:FieldModifier屬性的使用不需要手工修改對應控件后台代碼存取屬性,直接由XAML設置即可。
Silverlight命名空間和Windows 8命名空間的不同
例如,我們將添加新的引用“MyAssembly.dll”到項目,並且添加新的命名空間"MyAssembly.MyNamespace"到XAML代碼, 在Silverlight中,命名空間定義:
xmlns:local="clr-namespace:MyAssembly.MyNamespace;assembly:MyAssembly"
在Windows 8中,命名空間將使用“using”替換“clr-namespace“,
xmlns:local="using:MyAssembly.MyNamespace"
今天暫時介紹到這里,歡迎留言討論。
歡迎大家留言交流,或者加入QQ群交流學習:
22308706(一群) 超級群500人
37891947(二群) 超級群500人
100844510(三群) 高級群200人
32679922(四群) 超級群500人
23413513(五群) 高級群200人
32679955(六群) 超級群500人
88585140(八群) 超級群500人
128043302(九群 企業應用開發推薦群) 高級群200人
101364438(十群) 超級群500人
68435160(十一群 企業應用開發推薦群)超級群500人