【转】http://www.cnblogs.com/jv9/archive/2012/05/28/2520731.html
上一篇曾提及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"