XAML —— 命名空间

来源:互联网 发布:java接口的好处 编辑:程序博客网 时间:2024/06/10 15:43

命名空间的作用

XAML 命名空间的作用主要分为两种:

  1. 避免命名冲突。
  2. 使得标记元素与对应类型、属性映射。

第一点比较容易理解,就不多做解释;关于第二点,前面提到过,WPF 可以将 XAML 中声明的元素、属性映射到 .NET 中对应的类与属性,而之间的映射关系,就在对应的命名空间中。

XAML 命名空间与 XML 命名空间遵守相同的语法规则,即:xmlns[:namespace-prefix]="namespaceURI"。

默认命名空间

当创建一个 WPF 项目时,基本上所有的 XAML 文件都会包含以下命名空间:

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
第一个命名空间包含整个 WPF 的框架,它是一个默认的命名空间,通俗点说就是没有前缀的命名空间。

<Window x:Class="WpfApplication.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        Title="MainWindow" Height="350" Width="525">    <Grid>        <Button /    </Grid></Window>

当我们使用 Window、Grid、Button 等时,看似是没有用到命名空间,其实是使用了默认的命名空间,即:xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

当然,默认命名空间并不是必须的,我们可以为其添加一个前缀,将其改为:xmlns:demo="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

可以发现,如果只是简单的添加这个前缀的话,是没有办法编译通过的。那是因为系统找不到 Window、Grid、Button 等对象或者属性的映射关系。想要成功运行,必须将原来存在于默认命名空间的元素添加对应的前缀,即:

<demo:Window x:Class="WpfApplication.MainWindow"        xmlns:demo="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        Title="MainWindow" Height="350" Width="525">    <demo:Grid>        <demo:Button />    </demo:Grid></demo:Window>

当然,这样做纯粹是没事找抽,在实际项目开发中是不会这样做的。

x:命名空间

系统将 http://schemas.microsoft.com/winfx/2006/xaml 映射到 x 前缀。x 是 XAML 的第一个字母,当然这个只是默认的,而不是必须的,将其修改为 y、z 也完全可以。需要注意的是,虽然 WPF 使用 XAML 开发 UI,但是并不代表只有 WPF 使用 XAML 。实际上 XAML 也是一个很大的分支。而该命名空间就是包含 XAML 本身的一些功能。

在微软看来(当然,实际情况确实是这样),利用 WPF 进行开发的过程中,使用 WPF 框架功能会远远多余使用 XAML 语言的功能,所以微软将 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

作为默认的命名空间。

下面简单介绍下在项目中经常用到的在 x: 命名空间的指令:

名称功能x:Class指定该 XAML 的 Code Behind 的类x:Key为在 ResourceDictionary 中资源设置 Keyx:Null与 C# 中的 null 等价x:Static当在 XAML 中使用静态值时需要使用该指令x:Type与 C# 中的 typeof 等价x:Name为对象指定名称,可以通过该名称引用该对象

映射到类

在 XAML 中每声明一个元素,实际上就是映射到 .NET 中对应的类或属性。如果我们想要使用不在默认命名空间中的类,该怎么办?这就用到了 xmlns 前缀声明。利用该方式,可以将 XAML 命名空间映射到程序集,这个与将 WPF 框架、XAML 命名空间映射到前缀相似。

语法:clr-namespace:CLR Namespace;assembly=Assembly Name

using System.Windows.Controls;namespace WpfApplication{    public class CustomButton : Button    {        public CustomButton()        {        }    }}
如果想在 XAML 中使用该 CustomButton,只需要在 XAML 添加如下代码:

<Window x:Class="WpfApplication.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:control="clr-namespace:WpfApplication;assembly=WpfApplication"        Title="MainWindow" Height="350" Width="525">    <Grid>        <control:CustomButton />    </Grid></Window>

如果,XAML 所在的 Project 与该自定义类型的 Project 是相同的话,assembly 信息需要省略:clr-namespace:CLR Namespace 

Assembly 置空与不填 Assembly 信息是等价的,即上述语法等价于: clr-namespace:CLR Namespace;assembly=

如果在同一 Project,可以修改为:

<Window x:Class="WpfApplication.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:control="clr-namespace:WpfApplication"        Title="MainWindow" Height="350" Width="525">    <Grid>        <control:CustomButton />    </Grid></Window>

类似的,如果我们想在 XAML 中使用 String 对象:

<Window x:Class="WpfApplication.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        xmlns:system="clr-namespace:System;assembly=mscorlib"        Title="MainWindow" Height="350" Width="525">    <Window.Resources>        <system:String x:Key="Value">This is a string</system:String>    </Window.Resources>    <Grid>    </Grid></Window>

XmlnsDefinitionAttribute

可以看到我们写的映射到类(非 WPF 框架中的类)的语法与映射到 WPF 框架、XAML 功能的语法还是有些不同的

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:control="clr-namespace:WpfApplication;assembly=WpfApplication"

我们不禁会想如何将引用方式变得和系统的一样。这就是 XmlnsDefinitionAttribute 的作用了。它是 WPF 定义的一个 CLR Attribute,它的作用是告诉 XAML 处理器,将 CLR Namespace 映射到 XAML Namespace。

我们只需要在 AssemblyInfo.cs 文件中加上

[assembly: XmlnsDefinitionAttribute("http://schema.philip.com/control", "WpfApplication")]

就可以了。它将 WpfApplication Namespace 映射到 http://schema.philip.com/control。当然我们可以将多个 CLR Namespace 映射到同一个 XAML Namespace。

[assembly: XmlnsDefinitionAttribute("http://schema.philip.com/control", "CustomControl")][assembly: XmlnsDefinitionAttribute("http://schema.philip.com/control", "ThirdPartControl")]

当然,这样写需要注意以下三点:

1. 这两个命名空间中的类没有相同的名称,否则就会出现命名冲突。

2. XmlnsDefinitionAttribute 的作用是将在当前 Assembly 中的 CLR Namespace 映射为 XAML Namespace。

3. 映射后的 XAML Namespace 对使用该 Assembly 的 Project 有效。如在 Project A 中定义了XmlnsDefinitionAttribute,但是在当前 Project,即 Project A 中使用时,还是需要用clr-namespace:CLR命名空间的形式。

当然,我们也可以将自定义的类映射到系统定义的 XAML 命名空间中,如:

[assembly: XmlnsDefinitionAttribute("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "WpfApplication")]

这样,我们以后使用的时候,就不需要在重新添加映射空间了。但这样做千万注意是否会发生命名冲突。

回过头来看默认命名空间,其实也没有那么神秘,只不过定义 WPF 框架时使用了XmlnsDefinitionAttribute 罢了,WPF 将下述 CLR Namespace(只列出部分) 映射到了 http://schemas.microsoft.com/winfx/2006/xaml/presentation。

System.Windows
System.Windows.Controls
System.Windows.Controls.Primitives
System.Windows.Data
System.Windows.Documents
System.Windows.Input
System.Windows.Media
System.Windows.Media.Animation
System.Windows.Media.Effects
System.Windows.Media.Imaging

0 0
原创粉丝点击