x名称空间详解
第一篇的时间提到过一个xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml.没有详细的去解释,本文就去记录一下x的情况。
一、x名称空间都有什么
有了x,XAML编译器就会知道XAML怎么解析和编译,所以关于x命名空间里面的内容都与解析和编译有关。x名称空间的主要的内容如下:
1. Attribute类: x:Class, x:ClassModifier, x:FieldModifier, x:Key, x:Name, x: Shared
2.标签扩展类: x:Array, x:Null, x:Static, x:Type
二、x名称空间的Attribute
2.1 x:ClassModifier
介绍x:ClassModifier之前还是要说一下X:Class,由于有前者的标签必须要有后者标签,因为ClassModifier是用来修饰class的,主要来说明Class的访问级别,x:class是告诉窗口要编译成说明类,ClassModifier把类指定为怎么样的访问权限。下面看一个例子如图1:
图1
接下来看看IL反汇编程序类是以private的访问权限出现的(程序集的访问级别internal和private是相同的),如图2:
图2 图3
2.2 x:Name
编译器把x:Name编译成类的属性了,何以得来?下面就来证实一下。如果在一个TextBox标签里加上 x:Name="textbox1" 再看看IL反汇编程序如图3。现在终于知道为什么this.textbox1指的是这个控件了。至于x:Name与Name的差别,在于有的控件没有Name功能,也就是说前者更实用,所以建议都用前者。
2.3 x:FieldModified
x:FieldModified与x:Name的关系和x:ClassModifier与x:Class的关系差不多,都是前者设置后者的访问级别,并且与有x:Name必须有x:Class保持一致。引用方式为:<Slider x:Name="slider1" Margin="5" x:FieldModifier="public"/> 。由于上面已经说过x:ClassModifier与x:Class的关系,在此不再罗嗦。
2.4 x:Key
在c#中最自然的检索方式莫过于实用键值对“Key-Value”的形式,在XAML中会有使用多次资源,我们如果把资源放到资源字典里,就可以通过Key来检索出来了。好了还是利用例子更能说明问题,现在把一个string类型的资源放到资源字典里面,通过XAML和.CS两种形式显示到文本框里面。现在贴出前台代码和后台代码:
<Window x:Class="xNameSpace.xKey" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="xKey" Height="300" Width="300"> <Window.Resources> <sys:String x:Key="myString">Hello WPF!</sys:String> </Window.Resources> <StackPanel> <TextBox Text="{StaticResource ResourceKey=myString}" Margin="5"/> <TextBox x:Name="textBox2" Margin="5"/> <Button Content="Show" Click="Button_Click" Margin="5"/> </StackPanel> </Window>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace xNameSpace { /// <summary> /// xKey.xaml 的交互逻辑 /// </summary> public partial class xKey : Window { public xKey() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { string str=this.FindResource("myString") as string; this.textBox2.Text = str; } } }
运行结果如图4,点击按钮如图5
图4 图5
本程序需要注意四点
1、mlns:sys="clr-namespace:System;assembly=mscorlib"先引出程序命名空间,上面的是string的命名空间。
2、<Window.Resources><sys:String x:Key="myString">Hello WPF!</sys:String></Window.Resources>定义资源并放入资源字典里面。
3、<TextBox Text="{StaticResource ResourceKey=myString}" Margin="5"/>引用资源,这个是一个标签扩展,其实很简单,花括号里面前面是类型名,后面是一个属性=value。
4、string str=this.FindResource("myString") as string;后台找资源的时间是用()不是[],因为这里的FindResource是窗体的方法。
2.5 x:shared
声明资源是否共享,一定要和x:key配合使用。现在直接给出微软的官方作用:当设置为 false 时,会修改 WPF 资源检索行为,以便特性化资源请求为每个请求创建一个新实例,而不是所有请求共享同一个实例。可能读完感到没有头绪,我读完也不知道是怎么回事,但是网上一查,发现有篇文章(http://www.cnblogs.com/qc1984326/archive/2009/04/28/1445743.html)告诉了我答案。先上代码了
<Window x:Class="xNameSpace.xShared" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="xShared" Height="300" Width="300"> <Window.Resources> <SolidColorBrush x:Shared="false" x:Key="brush" Color="red" ></SolidColorBrush> </Window.Resources> <Grid x:Name="grid" > <Button Content="变色" Height="23" HorizontalAlignment="Left" Margin="73,156,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" /> <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="21,44,0,0" Name="button2" VerticalAlignment="Top" Width="75" Background="{StaticResource ResourceKey=brush}"/> <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="137,44,0,0" Name="button3" VerticalAlignment="Top" Width="75" Background="{StaticResource ResourceKey=brush}"/> </Grid> </Window>
private void button1_Click(object sender, RoutedEventArgs e)
{
SolidColorBrush scb = this.button2.Background as SolidColorBrush;
scb.Color=Colors.Green;
}
把x:Shared为false或true,运行两个按钮都是红色的,点变色按钮分别的效果为:
图6 图7
根据我的理解是这样的如果利用Shared=True的话是共享一个资源,如果改变了button的背景色,那么资源的值也就改变了,如果是为False的话,只会改变自己的颜色,与资源无关了,所以另外一个按钮就不会改变颜色了。微软:如果对资源的引用是静态资源引用,则在 XAML 处理时间之后的资源更改是不相关的。我改变标签扩展的StaticResource和DynamicResource效果是一样的,不知道是什么意思,希望有知道的大牛指点一下。
三、x名称空间的标记扩展
3.1 x:Type
Type本来就是framework里面的表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。还记的标记扩展有个特征是花括号里最左边的是其类型,x:Type就是一个花括号里的最左边的一个类。当在标记扩展里面想表达某个类的时间就可以用x:Type,还是通过一个例子说明其用法。需求是单击主窗体的按钮,显示另外一个窗体。由于这个Type是窗体,所以代码会有点多。先定义个MyButton类,使其继承Button类(如果是新手可以好好的体会一下关于这个类的设计,我这个菜鸟看了半天,才有那么一点点理解了)。代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Controls; using System.Windows; namespace xNameSpace { public class MyButton : Button { public Type UserWindowType { get; set; } protected override void OnClick() { base.OnClick(); //MessageBox.Show(this.UserWindowType.ToString()); Window win = Activator.CreateInstance(this.UserWindowType) as Window; if (win != null) win.ShowDialog(); } } }
然后再添加一个窗体Mywindow,然后编译一下,否则可能会在后面找不到MyWindow。最后添加主窗体Window1,后台代码默认,XAML代码(注意在开始的时间引入命名空间 xmlns:local="clr-namespace:xNameSpace" ,以及里面的<local:MyButton Content="show" UserWindowType="{x:Type TypeName=local:MyWindow}" Margin="5"/>代码)如下:
<Window x:Class="xNameSpace.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:xNameSpace" Title="Window1" Height="300" Width="300"> <StackPanel> <local:MyButton Content="show" UserWindowType="{x:Type TypeName=local:MyWindow}" Margin="5"/> </StackPanel> </Window>
单击Window1上的按钮就可以显示新建的窗体了。
3.2 x:null
主要在设置style时用的比较多,定义指定的风格后,想让某一个控件不适用次风格的话就可以用x:null。看一个例子,本例也有用到x:Type,顺便复习一下上面的内容。XAML代码
1 <Window x:Class="xNameSpace.xNull" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="xNull" Height="300" Width="300"> 5 <Window.Resources> 6 <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}"> 7 <Setter Property="Width" Value="60"/> 8 <Setter Property="Height" Value="36"/> 9 <Setter Property="Margin" Value="5"/> 10 <Setter Property="Background" Value="Red"/> 11 </Style> 12 </Window.Resources> 13 <StackPanel> 14 <Button Content="OK"></Button> 15 <Button Content="OK"></Button> 16 <Button Style="{x:Null}" Content="OK"></Button> 17 </StackPanel> 18 </Window>
运行结果:
图 8
Style的章节还会用到,在此只是简单的适用一下。
3.3 x:Array
经过了上面的例子应该可以猜出x:Array标签类型是数组,在绑定listbox时间可以做其数据源。
<ListBox Margin="5"> <ListBox.ItemsSource="{x:Array}" </ListBox>
这样写的话会报错,所以我们利用以前讲过属性标签。代码为
<Window x:Class="xNameSpace.xArray" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="xArray" Height="300" Width="300"> <Grid> <ListBox Margin="5"> <ListBox.ItemsSource> <x:Array Type="sys:String"> <sys:String>我是listbox</sys:String> <sys:String>我是来测试x:Array的</sys:String> </x:Array> </ListBox.ItemsSource> </ListBox> </Grid> </Window>
效果图如图9:
图 9
3.4 x:Static
x:Static是一个很常见的标签扩展,它的功能是在XAML文档中使用数据类型的Static成员。在后台添加一个静态变量:public static string staticStr = "我是静态变量"; ,在XAML中引用本地程序集:xmlns:local="clr-namespace:xNameSpace", 然后在textbox里面显示静态变量的值,代码为<TextBox Text="{x:Static local:xStatic.staticStr}"/>,其中xStatic为窗体名字。最后显示结果如图10:
图10
四、总结
本文主要记录了x命名空间里的两大类(Attribute类和标记扩展类)主要的内容,根据情况去选择使用,想熟练的使用还需要一段时间的练习,主要难点在于记住各个功能的格式和使用场合。还有就是在理解x:Shared的时间花了一下功夫。如果有不足的地方,请大牛们指点。谢谢阅读!下一篇:控件和布局