[No000013F]WPF学习之X名称空间详解

原文:[No000013F]WPF学习之X名称空间详解

X名称空间里面的成员(如X:Name,X:Class)都是写给XAML编译器看的、用来引导XAML代码将XAML代码编译为CLR代码。

4.1X名称空间里面到底都有些什么?

x名称空间映射的是:http://schemas.microsoft.com/winfx/2006/xaml,望文生义,它包含的类均与解析XAML语言相关,所以亦称之为“XAML名称空间”。

与C#语言一样,XAML也有自己的编译器。XAML语言被解析并编译,最终形成微软中间语言保存在程序集中。在解析和编译XAML的过程中,我们经常要告诉编译器一些重要的信息,如XAML编译的结果应该和哪个C#代码编译的结果合并、使用XAML声明的元素是public还是private访问级别等等。这些让程序员能够与XAML编译器沟通的工具就存在X:名称空间中。

我们注意到,它分为Attribute、标签扩展、XAML指令元素三个种类。下面我们讲讲它们的具体用法:

4.2      X名称空间中的Attribute

前面我们已经讲过,Attribute和Property是两个层面上的东西,Attribute是语言层面上的东西,是给编译器看的,Property是面向对象层面上的东西,是给编程逻辑看。而且一个标签中的Attribute大部分对应对象的Property。在使用XAML编程的时候,如果你想给它加一点特殊的标记来改变XAML对它的解析,这时候就需要额外的给它添加一些Attribute了。比如,你想告诉XAML编译器将哪个编译结果和那个C#编译的类合并,这时候就必须为这个标签添加X:Class  Attribute来告诉编译器。X:Class并不是对象成员,而是重X空间硬贴上去的。让我们浏览一下常用的Attribute。

4.2.1    x:Class

这个Attribute是告诉XAML编译器将XAML编译器编译的结果和后台编译结果的哪一个类进行合并,使用x:Class有以下几点要求:

  • 这个Attribute只能用于根节点。
  • 使用x:Class的根节点的类型要与x:Class的值所指示的一致。
  • x:Class的值所指示的类型在声明的时候必须使用partial关键字。
  • x:Class已经在剖析最简单的XAML的时候已经讲过,在这就不多讲了。

4.2.2     X:ClassModiffier

这段代码是告诉XAML编译器有标签编译成的类具有什么样的访问级别。

使用这个Attribute的时候需要注意的是:

  • 标签必须具有x:Class Attribute。
  • X:ClassModiffier的值必须与X:Class所指定类的访问权限一致。
  • X:ClassModiffier的值随后台代码编译语言的不同而有所不同。

4.2.3    X:Name

我们之前已经提过XAML是一种声明式语言,但你是否想过XAML标签声明的是什么呢?其实,XAML标签声明的是对象,一个XAML对应着一个对象,这个对象一般是一个控件类的实例。在.NET平台上,类是引用类型。引用类型的实例一般都是以“引用者---实例”的形式成对出现的,而且我们只能通过引用者来访问实例。当一个实例不在被任何引用者引用的时候,它将作为内存垃圾被销毁。

常见的引用者是引用变量,但不是唯一的。比如下面这段XAML代码:

  1. <Window x:Class="WpfApplication2.Window5"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. Title="Window5" Height="300" Width="300">
  5. <Grid>
  6. <StackPanel Height="218" HorizontalAlignment="Left" Margin="19,31,0,0"  VerticalAlignment="Top" Width="237">
  7. <TextBox Height="23" Width="120" />
  8. <Button Content="Button" Height="23" Width="75" />
  9. </StackPanel>
  10. </Grid>
  11. </Window>

这篇代码中通篇没有出现一次名字,但是我们可以通过引用者的层级关系来找到我们最终想要的控件,我们在Button的Click下写如下代码:

  1. private void Button_Click(object sender, RoutedEventArgs e)
  2. {
  3. StackPanel panel = this.Content as StackPanel;
  4. TextBox textBox = panel.Children[0] as TextBox;
  5. if (!string.IsNullOrEmpty(textBox.Name))
  6. {
  7. textBox.Text = textBox.Text;
  8. }
  9. else
  10. {
  11. textBox.Text = "NULL";
  12. }
  13. }

this.Content引用着StackPanel的实例,StackPanel.Children[0]又引用着TextBox的实例。知道了这个关系,就可以一路顺着查找下来并同时进行类型转换,最终TextBox中显示的值是NULL。

理论上我们可以用上面的方法访问到UI上的所有元素,但这毕竟太麻烦了。换句话说:XAML这种对象声明语言只负责声明对象而不负责为这些对象声明引用变量。如果我们需要为对象准备一个引用变量以便在C#中直接访问就必须显示的告诉XAML编译器-----为这个对象声明引用变量,这时候,X:Name就派上用场了。

注意:

X:Name的作用有两个:

(1)告诉编译器,当一个标签带有x:Name时,除了为这个标

这个还真不能确定!签生成实例还要给这个标签声明一个引用变量,变量名就是x:Name的值。

(2)将XAML标签所对应的Name属性(如果有)也设置为x:Name值,并把这个值注册到UI树上,以方便查找。

4.2.4     x:FieldModifier

使用了x:Name后,XAML标签对应的实例就具有了自己的引用变量,而且这些引用变量都是类的字段,既然这样就不免要关注一下它的访问级别。默认情况下这些字段的级别都被设置成了Internal。在编程的时候,有的时候需要用一个程序集里的一个窗体元素访问到另一个程序集的窗体元素,那么就需要使用x:FieldModifier来改变变量的访问级别!

  1. <StackPanel Height="218" HorizontalAlignment="Left" Margin="19,31,0,0"  VerticalAlignment="Top" Width="237">
  2. <TextBox Height="23" Width="120" x:Name="txtName" x:FieldModifier="internal"/>
  3. <Button Content="Button" Height="23" Width="75" Click="Button_Click" x:Name="btntest" x:FieldModifier="public"/>
  4. </StackPanel>

因为x:FidleModifier是应用变量的访问级别,所以要配合x:Name一起使用。否则没有引用变量,何来引用变量访问级别。

4.2.5    x:Key

最自然的检索方式莫过于”key-value“的形式了。在XAML文件中,我们可以把需要多次使用的类容提取出来放在资源字典中,需要使用的时候就用这个资源的key将这个资源检索出来。

x:key的作用就是使用为资源贴上用于检索的索引。在WPF中,几乎每个元素都有自己的Resource属性,这个属性就是“key-value”的集合。只要把元素放进这个集合里,这个元素就成了资源字典中的一个条目。当然,为了能检索到这个条件,就必须为它添加x:Key。资源在WPF中非常重要,需要重复使用的XAML内容,如Style,各种Template和动画都需要放在资源里。

先让我们看XAML代码:

  1. <Window x:Class="WpfApplication2.Window4"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:sys="clr-namespace:System;assembly=mscorlib"
  5. xmlns:local="clr-namespace:WpfApplication2"
  6. Title="Window4" Height="369" Width="675">
  7. <Window.Resources>
  8. <local:Human x:Key="human" Child="ABC"></local:Human>
  9. <sys:String x:Key="myString">测试</sys:String>
  10. <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
  11. <Setter Property="Width" Value="30"></Setter>
  12. <Setter Property="Background" Value="black"></Setter>
  13. </Style>
  14. </Window.Resources>
  15. <Grid>
  16. <Label Content="{ StaticResource ResourceKey=myString}" Height="28" HorizontalAlignment="Left" Margin="177,81,0,0" Name="label1" VerticalAlignment="Top" />
  17. </Grid>
  18. </Window>

资源不但可以在XAML中使用,也可以在C#中访问,C#中使用如下方式:

  1. string str = this.FindResource("myString") as string;
  2. this.label1.Content = str;

4.2.6    x:Shared

学习x:key的时候我们已经了解到,如果把某个对象作为资源放入资源字典里后我们就可以把它们检索起来重复使用。那么每当我们检索到一个对象,我们得到的究竟是同一个对象呢,还是这个对像的一个副本呢?这就要看我们为x:Shared赋什么值了。x:Shared一定要与x:Key配合使用,如果x:Shared值为true,那么每次检索这个对象的时候,我们得到的都是同一个对象,反之,我们得到的就是这个对象的一个副本。默认这个值是true。也就是说我们使用的都是同一个对象。

4.3       x名称空间下的扩展标签

标记扩展实际就是一些MarkupExtension类的直接或间接派生类。x名称空间中就包含一些这样的类,所以称其为x名称空间标签的标记扩展。

4.3.1   x:Type

顾名思义,x:Type应该是一个数据类型的名称。一般情况下,我们在编程中操作的数据类型实例或者实例的引用。但有的时候我们也需要用到数据类型本身。

能让程序员在编程的层面上自由的操作这些数据类型,比如在不知道具体类型的情况下创建这个类型的实例并尝试调用它的方法,.NET命名空间里还包含了名为Type的类做为所有数据类型在编程层面上的抽象。

当我们想在XAML中表达某一数据类型就需要用到x:Type标记扩展。比如某个类的一个属性,它的值要求的是一个数据类型,当我们在XAML中为这个属性赋值是就需要用到x:Type。请看下面这个例子:

  1. <UserControl x:Class="WpfApplication2.UserControl1"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  6. mc:Ignorable="d"
  7. d:DesignHeight="52" d:DesignWidth="128">
  8. <Grid>
  9. <Button Content="Button" Height="30" HorizontalAlignment="Left" Margin="10,10,0,0" Name="button1" VerticalAlignment="Top" Width="106" Click="button1_Click" />
  10. </Grid>
  11. </UserControl>


  1. /// <summary>
  2. /// UserControl1.xaml 的交互逻辑
  3. /// </summary>
  4. public partial class UserControl1 : UserControl
  5. {
  6. public UserControl1()
  7. {
  8. InitializeComponent();
  9. }
  10. public Type MyWindowType { get; set; }
  11. private void button1_Click(object sender, RoutedEventArgs e)
  12. {
  13. Window myWin = Activator.CreateInstance(this.MyWindowType) as Window;
  14. if(myWin!=)
  15. {
  16. myWin.Show();
  17. }
  18. }
  19. }


  1. <Window x:Class="WpfApplication2.Window4"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:sys="clr-namespace:System;assembly=mscorlib"
  5. xmlns:local="clr-namespace:WpfApplication2"
  6. Title="Window4" Height="369" Width="675">
  7. <Window.Resources>
  8. <local:Human x:Key="human" Child="ABC"></local:Human>
  9. <sys:String x:Key="myString">测试</sys:String>
  10. <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
  11. <Setter Property="Width" Value="30"></Setter>
  12. <Setter Property="Background" Value="black"></Setter>
  13. </Style>
  14. </Window.Resources>
  15. <Grid>
  16. <local:UserControl1 HorizontalAlignment="Left" Margin="292,244,0,0" x:Name="userControl11" VerticalAlignment="Top" MyWindowType="{x:Type TypeName=local:Window1}"/>
  17. </Grid>
  18. </Window>

回顾一下之前的标记扩展语法,因为TypeExtension类的构造器可以接受数据类型名做为参数,所以我们完全可以这样写:

  1. UserWindowType="{x:Type local:Window1}"

编译并运行程序,单击主窗体上的按钮,自定义窗口就会显示出来,我们还可以多写几个窗体来扩展这个程序,到时后只需要修改MyWindowType里面的值就可以了。

4.3.2       x:Null

在XAML里面表示空值就是x:Null。

大部分时间我们不需要为属性附一个Null值,但如果一个属性就有默认值而我们有不需要这个默认值就需要用的null值了。在WPF中,Style是按照一个特定的审美规格设置控件的各个属性,程序员可以为控件逐个设置style,也可以指定一个style目标控件类型,一旦指定了目标类型,所有的这类控件都将使用这个style----除非你显示的将某个实例的Style设置为null。

请看下面的事例:

  1. <Window x:Class="WpfApplication2.Window4"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:sys="clr-namespace:System;assembly=mscorlib"
  5. xmlns:local="clr-namespace:WpfApplication2"
  6. Title="Window4" Height="369" Width="675">
  7. <Window.Resources>
  8. <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
  9. <Setter Property="Width" Value="30"></Setter>
  10. <Setter Property="Background" Value="black"></Setter>
  11. </Style>
  12. </Window.Resources>
  13. <Grid>
  14. <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="180,256,0,0" Name="button1" VerticalAlignment="Top" Click="button1_Click" />
  15. <Label Content="{ StaticResource ResourceKey=myString}" Height="28" HorizontalAlignment="Left" Margin="177,81,0,0" Name="label1" VerticalAlignment="Top" />
  16. <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="button2" VerticalAlignment="Top" />
  17. <Button Content="{x:Static local:Window4.Test}" Height="23" HorizontalAlignment="Left" Margin="128,12,0,0" Name="button3" VerticalAlignment="Top" Style="{x:Null}"/>
  18. </Grid>
  19. </Window>

当然了,x:null也可以使用属性标签来设置这个值,前面已经讲过,在这就不在讲了。

4.3.3       x:Array

通过它的item属性向使用者暴露一个类型已知的ArrayList实例,ArrayList内成员的类型由x:Array的Type指明。下面这个例子就是把ArrayList做为数据源向一个ListBox提供数据:

  1. <Window x:Class="WpfApplication2.Window4"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:sys="clr-namespace:System;assembly=mscorlib"
  5. xmlns:local="clr-namespace:WpfApplication2"
  6. Title="Window4" Height="369" Width="675">
  7. <Grid>
  8. <ListBox Height="100" HorizontalAlignment="Left" Margin="435,110,0,0" Name="listBox1" VerticalAlignment="Top" Width="176">
  9. <ListBox.ItemsSource>
  10. <x:Array Type="sys:String">
  11. <sys:String>Jim</sys:String>
  12. <sys:String>Darren</sys:String>
  13. <sys:String>Frank</sys:String>
  14. </x:Array>
  15. </ListBox.ItemsSource>
  16. </ListBox>
  17. </Grid>
  18. </Window>

4.3.4        x:Static

这是一个很常用的标记扩展,它的作用是在XAML文档中使用数据类型为static的成员。因为XAML不能编写逻辑代码。所以使用x:Static访问的static成员一定是数据类型的属性和字段。我们看如下一些例子:

  1. public Window4()
  2. {
  3. InitializeComponent();
  4. //SolidColorBrush brush = new SolidColorBrush();
  5. //brush.Color = Colors.Blue;
  6. //this.rectangle1.Fill = brush;
  7. }
  8. public static string Test = "明月松间照,清泉石上流。";
  1. <Window x:Class="WpfApplication2.Window4"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:sys="clr-namespace:System;assembly=mscorlib"
  5. xmlns:local="clr-namespace:WpfApplication2"
  6. Title="Window4" Height="369" Width="675">
  7. <Grid>
  8. <Button Content="{x:Static local:Window4.Test}" Height="23" HorizontalAlignment="Left" Margin="128,12,0,0" Name="button3" VerticalAlignment="Top" Style="{x:Null}"/>
  9. </Grid>
  10. </Window>

如果一个程序需要支持国际化,一般需要把显示的字符串保存在一个资源类的Static属性中,所以支持国际化的程序UI中对x:Static的使用相当的频繁。

4.4        XAML指令元素
XAML指令元素只有两个:

  • x:Code
  • x:XData

我们之前已经在代码后置一节介绍过x:Code标签,它的作用是可以在XAML文档中可以编写后置的C#后台逻辑代码,这样做的好处就是不需要把XAML和C#分放在两个文档当中,这样写的问题是代码不容易维护,不宜调试,一般没有人愿意这么干。

x:XData是一个专用标签。WPF把包含数据的对象称为数据源,用于把数据源中的数据提供给数据使用者的对象被称做是数据提供者,WPF中包含多种数据提供者,其中一个类名叫做XmlDataProvider实例,那么XmlDataProvider实例的数据就要放在x:XData的标签内容里。事例如下:

原文地址:https://www.cnblogs.com/lonelyxmas/p/10280149.html

时间: 2024-08-01 09:20:44

[No000013F]WPF学习之X名称空间详解的相关文章

php学习之道:WSDL详解(一)

WSDL文档使用web服务描述语言来定义服务. 文档包括逻辑(抽象)部分和具体部分. 抽象部分用于定义独立于实现的数据类型和消息,具体部分定义一个endpoint如何实现一个可以与外界进行交互的服务. 通常建议在写代码前定义WSDL文档和XML schema,但是这就要求对WSDL非常熟悉. 逻辑部分: 包括types,message以及portType元素.types元素中,xml schema用来定义组成消息的数据的结构.一定数量的消息元素用来定义服务所用消息的格式.portType元素包括

hadoop 学习笔记:mapreduce框架详解

hadoop 学习笔记:mapreduce框架详解 开始聊mapreduce,mapreduce是hadoop的计算框架,我 学hadoop是从hive开始入手,再到hdfs,当我学习hdfs时候,就感觉到hdfs和mapreduce关系的紧密.这个可能是我做技术研究的 思路有关,我开始学习某一套技术总是想着这套技术到底能干什么,只有当我真正理解了这套技术解决了什么问题时候,我后续的学习就能逐步的加快,而学习 hdfs时候我就发现,要理解hadoop框架的意义,hdfs和mapreduce是密不

J2EE学习篇之--JQuery技术详解

前面我们讲解了的J2EE的技术都是服务端的技术,下面我们来看一下前端的一些开发技术,这一篇我们来看一下jQuery技术 简介: jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. jQuery是继prototype之后又一个优秀的Javascript框架.其宗旨是--WRITE LESS,DO MORE,写更少的代码,做更多的事情. 它是轻量级的js库(压缩后只有21k) ,这是其它的js库所不及的,它兼容CSS3,还兼容各种浏

JavaScript学习总结(十一)——Object类详解

一.Object类介绍 Object类是所有JavaScript类的基类(父类),提供了一种创建自定义对象的简单方式,不再需要程序员定义构造函数. 二.Object类主要属性 1.constructor:对象的构造函数. 2.prototype:获得类的prototype对象,static性质. 三.Object类主要方法 1.hasOwnProperty(propertyName) 判断对象是否有某个特定的属性.必须用字符串指定该属性,例如,obj.hasOwnProperty("name&q

J2EE学习篇之--Struts2技术详解

前面说到了Struts1的相关知识,下面来说一下Struts2的相关知识,我们知道现在Struts2使用的比Struts1多,Struts2已经替代Struts1成为主流的框架了... 摘要 Struts2是在WebWork2基础发展而来的.和struts1一样, Struts2也属于MVC框架.不过有一点大家需要注意的是:尽管Struts2和Struts1在名字上的差别不是很大,但Struts2和struts1在代码编写风格上几乎是不一样的.那么既然有了struts1,为何还要推出struts

重新学习MySQL数据库7:详解MyIsam与InnoDB引擎的锁实现

重新学习Mysql数据库7:详解MyIsam与InnoDB引擎的锁实现 说到锁机制之前,先来看看Mysql的存储引擎,毕竟不同的引擎的锁机制也随着不同. 三类常见引擎: MyIsam :不支持事务,不支持外键,所以访问速度快.锁机制是表锁,支持全文索引 InnoDB :支持事务.支持外键,所以对比MyISAM,InnoDB的处理效率差一些,并要占更多的磁盘空间保留数据和索引.锁机制是行锁,不支持全文索引(5.6以上支持) Memory:数据是存放在内存中的,默认哈希索引,非常适合存储临时数据,服

好程序员web前端学习路线大厂面试题详解

好程序员web前端学习路线大厂面试题详解,依赖注入原理 手动实现依赖注入实现方式 - var _global={ - ajax:function(){//申明服务,也可以说是内部类 - this.get=function(){ - //todo:get方式请求数据 - console.log(“get is success”); - }; - This.post=function(){ - //todo:post方式请求数据 - console.log(“post is success”); -

php学习之道:WSDL详解(三)

通过声明方式定义绑定(binding)属性 如果你在服务中采用SOAP binding,你可以使用JAX-WS来指定一定数量的属性binding.这些属性指定对应你在WSDL中指定的属性.某些设置,比如参数类型,可以约束你实现的方法,这些设置也影响声明的效用. @SOAPBinding声明,定义在javax.jws.soap.SOAPBinding接口中.它提供发布时的SOAP Binding细节.如果@SOAPBinding没有被指定,则用缺省的doc/literal SOAPBinding.

Java学习-007-Log4J 日志记录配置文件详解及实例源代码

此文主要讲述在初学 Java 时,常用的 Log4J 日志记录配置文件详解及实例源代码整理.希望能对初学 Java 编程的亲们有所帮助.若有不足之处,敬请大神指正,不胜感激!源代码测试通过日期为:2015-1-30 13:54:02,请知悉. 所需的 jar 包下载链接为:http://yunpan.cn/cKE56sxqtQCfP  访问密码 63d8 有关 Log4J 日志文件中日志级别及文件配置的详细情况,在 Log4J 的配置文件(xml.properties)中有详细的介绍,敬请参阅!