针对WPF XAML的XAML命名空间和命名空间映射
本文将解释在WPF XAML文件的根标记中常见的两个XAML名称空间映射的存在和目的。它还描述了如何为使用在自己的代码中定义的元素和/或在单独的库文件中定义的元素生成类似的映射。
什么是XAML的命名空间
XAML名称空间实际上是XML名称空间概念的扩展。指定XAML名称空间的技术依赖于XML名称空间语法、使用uri作为名称空间标识符的约定、使用前缀提供引用来自同一标记源的多个名称空间的方法,等等。添加到XML名称空间的XAML定义中的主要概念是,XAML名称空间既意味着标记使用的唯一性范围,也影响标记实体被特定CLR名称空间和引用库的方式。后一种考虑也受到XAML模式上下文概念的影响。但是,为了说明WPF如何与XAML命名空间一起工作,您通常可以考虑默认的XAML命名空间、XAML语言命名空间和任何进一步的XAML命名空间,作为由XAML标记直接映射到特定的支持CLR命名空间和引用库的XAML命名空间。
WPF和XAML命名空间声明
在许多XAML文件的根标记中的名称空间声明中,您将看到通常有两个XML名称空间声明。第一个声明将整个WPF客户端/框架XAML命名空间映射为默认值:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
第二个声明映射了一个单独的XAML名称空间,并将它(通常)映射到x:前缀。
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
这些声明之间的关系是,x:前缀映射支持作为XAML语言定义的一部分的内在元素,而WPF是一种使用XAML作为一种语言的实现,并为XAML定义了其对象的术语。因为WPF术语的用法将比XAML的内在用法更常见,所以WPF术语被映射为默认用法。
用于映射XAML语言内部支持的x:前缀约定,后面是项目模板、示例代码和这个SDK中的语言特性文档。XAML名称空间定义了许多常用的特性,这些特性即使对于基本的WPF应用程序也是必需的。例如,为了把部分隐藏类将连接到XAML文件中,您必须将该类命名为相关XAML文件的根元素中的x::Class属性。或者,在XAML页面中定义的希望作为特定资源访问的元素应该在相关元素上设置x:Key属性。
映射到自定义类和组件
可以使用xmlns前缀声明中的一些标记将XML名称空间映射到库文件,这类似于标准的WPF和XAML内部的XAML名称空间映射到前缀的方式。
该语法采用以下可能的命名标记和以下值:
clr-namespace:在库中声明的CLR命名空间,其中包含要作为元素公开的公共类型。比如:
xmlns:charts="clr-namespace:MauiCharts.Charts"
assembly= 包含部分或全部被引用的CLR命名空间的库。此值通常只是库的名称,而不是路径,并且不包括扩展名(例如,.dll或.exe)。该库的路径必须在项目文件中建立引用,然后才能在XAML中映射。为了考虑版本控制和安全签名,库名称可以是由“库名称”定义的字符串,而不是简单的字符串名称。
请注意,将clr-namespace标记与其值分隔的字符是冒号(:),而将assembly标记与其值分隔的字符是等号(=)。在这两个标记之间使用的字符是分号。此外,不要在声明中包含任何空格。
一个基本的自定义映射示例
下面的代码定义了一个示例自定义类:
namespace SDKSample {
public class ExampleClass : ContentControl {
public ExampleClass() {
...
}
}
}
然后将这个自定义类编译成一个库,库名称指定为SDKSample。
为了引用这个自定义类,还需要将其作为当前项目的引用,一般会使用Visual Studio的解决方案资源管理器UI增加引用。
现在有了一个包含类的库,要在项目设置中对它的引用,可以在XAML中添加以下前缀映射作为根元素的一部分:
xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary"
为了把它们放在一起,下面是XAML,它包括自定义映射以及典型的默认映射和x:映射,然后使用一个带前缀的引用在该UI中实例化定制类:
<Page x:Class="WPFApplication1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary"> ...
<custom:ExampleClass/>
...
</Page>
映射到当前程序集
如果所引用的clr-namespace是在与引用自定义类的应用程序代码相同的程序集中定义的,则可以省略assembly。或者,这种情况下的等价语法是指定库=,在等号后面没有字符串标记。
在同一个库中定义,则自定义类不能用作页面的根元素。不需要映射部分类;如果您打算在XAML中作为元素引用它们,则只需要映射应用程序中不是页面的部分类的类。
将CLR命名空间映射到库中的XML命名空间
WPF定义了一个由XAML处理器使用的CLR属性,以便将多个CLR名称空间映射到单个XAML名称空间。此属性 XmlnsDefinitionAttribute,,被放置在生成库的源代码中的库级别。WPF汇编源代码使用此属性来映射各种公共名称空间,如 System.Windows and System.Windows.Controls, 映射到 http://schemas.microsoft.com/winfx/2006/xaml/presentation
XmlnsDefinitionAttribute属性包含两个参数:XML/XAML命名空间名称和CLR命名空间名称。可以存在多个CLR名称空间映射到同一个XML名称空间。一旦映射完毕,您也可以通过在部分类代码隐藏页面中提供适当的使用语句来不完全限定地引用这些名称空间的成员。
WPF和装配加载
WPF的XAML模式上下文与WPF应用程序模型集成,该应用程序模型又使用了clr定义的 AppDomain概念。下面的序列描述了XAML模式上下文如何解释如何在基于AppDomain的WPF使用和其他因素的情况下,在运行时或设计时加载程序集或查找类型。
- 迭代整个AppDomain,从最近加载的库开始查找已加载的匹配名称的所有方面的库。
- 如果该名称已限定,请调用Assembly.Load(String)限定名称上的(字符串)。
- 如果限定名称的短名称+公钥标记与加载标记的库匹配,则返回该库。
- 使用短名称+公钥令牌来调用Assembly.Load(String))。
- 如果名称不合格,请调 Assembly.LoadWithPartialName。
Loose XAML不使用步骤3;没有从库加载。
为WPF编译的XAML(通过XamlBuildTask生成)不使用 AppDomain中已经加载的库(步骤1)。此外,名称不应该对XamlBuildTask输出不合格,因此步骤5不适用。
编译的BAML(通过演示文稿构建任务生成)使用所有步骤,尽管BAML也不应该包含不合格的库名称。