x名称空间由来:
x名称空间里的成员是专门为XAML编译器看的,用来引导XAML编译器把XAML编译成CLR代码,因此x是XAML的首字母。通过x空间的成员告诉编译器怎么编译XAML,生成什么类名,属性的可访问性等。
x命名空间包含的工具
名称 | 种类(在XAML中出现的形式) |
---|---|
x:Array | 标签扩展 |
x:Null | 标签扩展 |
x:Static | 标签扩展 |
x:Type | 标签扩展 |
x:Class | Attribute |
x:ClassModifier | Atteribute |
x:FieldModifter | Atteribute |
x:Key | Atteribute |
x:Name | Atteribute |
x:Shared | Atteribute |
x:Subclass | Atteribute |
x:TypeArguments | Atteribute |
x:Uid | Atteribute |
x:Code | XAML指令元素 |
x:XData | XAML指令元素 |
x名称空间中的Attribute:
x:Class,用来告诉XAML编译器把XAML标签的编译结果与后台代码的哪个类合并,只能用于根节点,并且根节点的类型要与后台代码的类保持一致。
x:ClassModifier,用来告诉XAML编译器把XAML标签编译成的类具有怎样的访问级别,必须具有x:Class Attribute的标签才能应用,并且与指定的后端代码访问级别一致。
x:Name,它的作用有两个:(1)告诉XAML编译器,当一个标签带有x:Name时除了为这个标签生成对应实例外还要为这个实例声明一个引用变量,变量名就是x:Nmae的值。(2)将XAML标签所对应对象的Name属性(如果有)也设为x:Name的值,并把这个值注册到UI树上,以方便查找。
x:FieldModifier,用来告诉XAML编译器由该标签生成的类的字段的访问级别,默认为internal。在编程的时候,有时候我们需要从一个程序集访问另一个程序集中的元素,这时就需要把被访问的空间的引用变量改为Public级别,x:FieldModifier就是用在XAML里改变引用变量访问级别。
<StackPanel>
<TextBox x:Name="textBox1" x:FieldModifier="public" Margin="5"/>
<TextBox x:Name="textBox2" Margin="5"/>
</StackPanel>
注意:因为x:FieldModifier是用来改变引用变量访问级别的,所以使用它的前提是这个标签同时也是用了x:Name,不然何来的引用变量呢?
x:Key,为资源字典指定key值,在XAML中通过StaticResource标记扩展进行资源检索时使用,并且可以自动向父级元素检索并一直递归直到找到该资源或到达Application。通过在代码中使用.FindResource方法也可以进行递归检索资源。
x:Shared,与x:Key配合使用,用来指定检索资源对象时,是使用同一个对象副本还是不同的对象,默认x:Share=“True”,因此资源检索得到的是同一个对象。
x名称空间中的标记扩展:
x:Type,类型为TypeExtension的标记扩展,用来在XAML中指定Type类型,与C#中的typeof关键字类似。x:Type的默认参数为类型,如{x:Type local:MyWindow}或{x:Type TypeName=local:MyWindow}。
x:Null,类型为NullExtension的标记扩展,用来在XAML中显示为属性指定Null值,如果在资源字典中定义了Style并把key和TargetType都指定为目标类型,则目标类型的所有标签都默认使用该Style。如果控件不想使用默认Style,则可以为Style指定null,如Style={x:Null}。如下图所示:
<Button Content="OK">
<Button.Style>
<x:Null/>
</Button.Style>
</Button>
为了保持代码简洁,一般很少用,但有一个例外,那就是 x:Array 标记扩展——如果想要在XAML文档中声明一个包含数据x:Array
实例,必须使用标签式声明才能做到。
x:Array,它的作用就是通过它的Items属性向使用者暴露一个类型已知的ArrayList实例,ArrayList内成员的类型由 x:Array 的Type指明。下面的这个例子是把一个x:Array当做数据源向一个ListBox提供数据。
在WPF中包含数据的对象称为数据源(Data Source),如果想把一个x:Array的实例作为数据源提供给一个ListBox的话,代码是这样写的:
<Windows x:Class="WpfApplication1.Windows1"
···
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Window1" Height="120" Width="160">
<Grid Background="LightBlue">
<LisBox Margin="5" ItemsSource="{x:Array Type=sys:string}"/>
</Grid>
</Windows>
此时,作为数据源的x:Array 实例是没有数据提供的,所以我们需要在x:Array实例添加一些数据。但由于向ArrayExtension中添加数据需要调用它的AddChild方法,但在XAML中我们无法编写逻辑代码,并且ArrayExtension的Items属性是只读的,所以我们不可能用ItemsSource=“{x:Array Type=sys:String Items=XXXXX}”的形式赋值,只能使用标签语法,如以下代码片段
<ListBox>
<ListBox.ItemsSource>
<x:Array Type="sys:String">
<sys:String>String1</sys:String>
<sys:String>String2</sys:String>
<sys:String>String3</sys:String>
</x:Array>
</ListBox.ItemsSource>
</ListBox>
这样,在解析标签的时候编译器会生成调用AddChild方法的代码把标签的子元素逐个添加到x:Array实例的Iteams里。
x:Static,类型为StaticExtension的标记扩展,用来在XAML中引用类的静态字段或静态属性,如Text={x:Static local:Window1.ShowText}。
XAML指令元素:
XAML指令元素只有两个,x:Code和x:XData,x:Code用来把C#代码放到XAML中,x:XData用来为数据提供者提供数据,如以下代码片段
<Page.Resources>
<XmlDataProvider x:Key="asdf">
<x:XData>
<Root>
<Item>Item1</Item>
<Item>Item2</Item>
</Root>
</x:XData>
</XmlDataProvider>
</Page.Resources>