2.1 新建WPF项目 ### 略
2.2 剖析最简单的XAML代码
XAML是XML派生的
为了表示同类标签中的某个标签与众不同,可以给它的特征(Attribute)赋值,赋值语法如下:
非空标签:<Tag Attribute1=Value1 Attribute2=Value2>Content</Tag>
空标签:
Property和Attribute的区别
Property属于面向对象理论范畴,类中用来表示事物状态的成员就是Property。
Attribute则是编程语言文法层面的东西,Attribute只与语言层面上的东西相关,与抽象出来的对象没什么关系。
xmlns是XML-Namespace的缩写,语法为:
xmlns[:可选的映射前缀]=”名称空间”
xmlns后面可以跟一个可选的映射前缀,用冒号分隔。如果没有使用可选的映射前缀,那就意味着所有来自这个名称控件的标签都不用加前缀,这个没有映射前缀的名称空间称为”默认名称空间”----默认名称空间只能有一个。
XAML中引用外来程序集和其中.NET名称空间语法与C#不一样。如果要添加System.Windows.Controls名称空间里的Button类,在XAML中首先需要添加对指定程序集的引用,然后在根元素的起始标签中添加如下代码:xmlns:c=”clr-namespace:System.Windows.Controls;assembly=PresentationFramework”。
c是映射前缀,换成其他字符也是可以的。因为这里Button来自前缀c对应的名称空间,所以使用Button的时候要写成
第三章 系统学习XAML语法
3.1 XAML文档的树形结构
在用户眼中UI是一个平面的结构。
在传统的VC++、Delphi、VB或者WinForm程序员的思维中,UI也是一个平面结构。
XAML用树形逻辑结构来描述UI。
WPF基本类库为程序员准备了VisualTreeHelper和LogicalTreeHelper两个助手类。
选择哪种方法实现UI的依据:
设计师在XAML上给出UI的布局是软件的一个静态快照(Static Snap),这个静态快照需要加上用户有可能执行的动态操作才能构成选择布局实现方法的完整依据。
3.2 XAML中为对象属性赋值的语法
XAML中为对象属性赋值共有两种语法:
使用字符串进行简单赋值
使用属性元素(Prperty Element进行复杂赋值)
3.2.1 使用标签的Attribute为对象属性赋值
使用Attribute=Value语法赋值的时候,由于XAML的语法限制,Value只可能是一个字符串,这就引出了两个问题:
如果一个类能使用XAML语言进行声明,并允许它的property与XAML标签的Attribute互相映射,那就需要为这些Property准备适当的转换机制。
由于Value是一个字符串,所有其格式复杂程度有限,尽管可以在转换机制里包含一定的按格式解析字符串的功能以便转换成较复杂的目标对象,但这会让最终的XAML使用者头痛不已。因为他们不得不在没有编码辅助的情况下手写一个格式复杂的字符串以满足赋值要求。
第一个问题的解决方案是使用TypeConverter类的派生类,在派生类里重写TypeConverter的一些方法,第二个问题解决办法是使用属性元素(Property Element)。
3.2.2 使用TypeConverter类将XAML标签的Attribute与对象的Property进行映射
略 见书P19
3.2.3 属性元素
XAML中,非空标签都有自己的内容(Content)。
标签的内容指的是夹在起始标签和结束标签之间的一些子级标签,每个子级标签都是父级标签内容的一个元素(Element),简称父级标签的一个元素。
属性元素指的是某个标签的一个元素对应这个标签的一个属性,即以元素的形式来表达一个实例的属性。
简化XAML技巧:
能使用Attribute=Value形式赋值的就不使用属性元素
充分利用默认值,去除冗余。
充分利用XAML的简写方式。
3.2.4 标记扩展
标记扩展:所谓标记扩展,实际上是一种特殊的Attribute=Value语法,其特殊地方在于Value字符串是由一对花括号及其括起来的内容组成,XAML编译器会对这样的内容做出解析、生成相应的对象。
例子见P25
Text=”{Binding ElementName=slider1, Path=Value, Mode=OneWay}”分析如下:
当编译器看到这句代码时就会把花括号里的内容解析成相对应的对象
对象的数据类型名称是紧邻左花括号的字符串
对象的属性由一串以逗号连接的字符串负责初始化,对象的属性值不再加引号
只有MarkupExtension类的派生类(间接或者直接都可)才能使用标记扩展语法来创造对象
3.3 事件处理器与代码后置
XAML标签对应一个对象时,标签一部分Attribute会对应对象的Property,另外一部分Attribute对应对象的事件(Event)。
事件处理器(Event Handler):为对象的某个事件指定一个能与该事件匹配的成员函数,当这个事件发生时,.Net在运行时会去调用这个函数,即标识对这个事件的响应和处理。
WPF支持在XAML里为对象的事件指定事件处理器,方法是使用事件处理器的函数名为对应对象事件的Attribute进行赋值。格式为:<ClassName EventName=”EventHandlerName”>
代码后置(Code-Behind):标识UI的XAML文件和C#代码分别表示前台和后台,前台和后台用事件Attribute来沟通链接。
]]>
可以用此关键字把C#代码嵌入到XAML文件中(不推荐使用)
3.4 导入程序集和引用其中的名称空间
.NET的模块称为程序集(Assembly)
一个解决方案是一个完成的程序,解决方案中会包含若干项目(Project),每个项目是可以独立编译的,它的编译结果就是一个程序集。
XAML引用名称空间的语法:
xmlns是用于在XMAL中声明名称空间的Attribute,它从XML语法继承而来,是XML-Namespace的缩写
冒号后面的映射名是可选的,但由于可以不加映射名的默认名称空间已经被WPF的主要名称空间占用,所以所引用的名称空间都需要加上这个映射名,映射名可以根据喜好自由选择
引号中的字符串值确定了你要引用的是哪个类库及类库中的哪个名称空间。
使用引用的类格式:<映射名:类名>……</映射名:类名>
3.5 XAML的注释
<!—注释内容-->
第四章 x名称空间详解
x名称空间的x是映射XAML名称空间时给它取得名字;x名称空间里的成员是专门写给XAML编译器看,用来引导XAML编译器把XAML代码编译成CLR代码的。
4.1 x名称空间里都有什么
x名称空间映射一般为http://schemas.microsoft.com/winfx/2006/xaml
XAML也有自己的编译器,XAML语言会被解析并编译,最终形成微软中间语言存储在程序集中
x名称空间中包含的工具列表见P31
x名称空间中的Attribute
4.2.1 x:Class
这个Attribute作用是告诉XAML编译器将XAML标签的编译结果与后台代码中指定的类合并,在使用x:Class时必须遵循以下要求:
这个Attribute智能用于根节点
使用x:Class的根节点的类型要与x:Class的值所指示的类型保持一致
x:Class的值所指示的类型在声明时必须使用partial关键字
x:Class已经在剖析最简单的WPF程序时讲过,此处不在赘述
4.2.2 x:ClassModifier
这个Attribute作用是告诉XAML编译由标签生成的类具有怎么样的访问控制级别
使用x:ClassModifier时需要注意事项:
标签必须具有 x:Class Attribute
x:ClassModifier的值必须与x:Class所指示类的访问控制级别一致
x:ClassModifier的值随后台代码的编译语言不同而有所不同,具体参看TypeAttributes枚举类型
4.2.3 x:Name
XAML标签是对象,一个XAML变迁对应着一个对象,这个对象一般是一个控件的实例。
不带名称的XAML对象声明只负责声明对象而不负责为这些对象声明引用变量。
如果我们需要为对象准备一个引用变量以便在C#代码中直接访问就必须显示告诉XAML编译器,为这个对象声明引用变量就要用到x:Name
x:Name的作用有两个:
告诉XAML编译器,当一个标签带有x:Name时除了为这个标签生成对应实例以外还要为这个实例声明一个引用变量,变量名就是x:Name的值
将XAML标签所对应对象的Name属性(如果有)也设置为x:Name的值,并把这个值注册到UI树上以方便查找
问题:在XAML代码中应该使用Name还是x:Name
Name属性定义在FrameworkElement类中,这个类是WPF控件类的基类,所有的WPF控件都有Name这个属性。当一个元素具有Name属性时,使用Name或者x:Name效果是一样的。对于那些没有Name属性值的元素,为了在XAML声明时也创建引用变量以便在C#代码中访问,我们只能使用x:Name。
4.2.4 x:FieldModifier
x:FieldModifier用来在XAML里改变引用变量访问级别
使用x:Name后XAML标签对应实例具有自己的引用变量,而且这些引用变量都是类的字段。默认情况下,这些字段的访问级别按照面向对象的封装原则被设置成internal。有时候我们需要从一个程序集访问另外一个程序集中窗体的元素,这个时候需要把访问控件的引用变量改为public级别。
注意:因为x:FieldMOdifier是用来改变引用变量访问级别的,所有使用x:FieldModifer的前提是这个标签同时使用x:Name,否则无法通过Name来引用变量。
4.2.5 x:Key
在XAML文件中,我们可以把需要多次使用的内容提取出来放在资源字典(Resource Dicitonary)里,需用使用这个资源的时候用Key把它检索出来,x:Key的作用就是为资源贴上用于检索的索引。
Resources在WPF中非常重要,需要重复使用的XAML内容,例如:Style、各种Template和动画等都需要放在资源里。
4.2.6 x:Shared
x:Shared一定要与x:Key配合使用,如果x:Shared为true,那么每次检索到这个对象时,我们得到的都是同一个对象,否则得到的是这个对象的一个新副本,默认XAML会为资源隐式定义为true。
4.3 x名称空间中的标记扩展
x:Type的值应该是一个数据类型名称
在XAML中想表达某个数据类型时就需要使用x:Type标记扩展
代码示例见书P39
4.3.2 x:Null
显示的对一个属性赋予空值
4.3.3 标记扩展实例的两种声明语法
标记扩展也是标准的.NET类,所以我们也可以使用XAML的标签来声明标记扩展的实例。
代码示例:
第一种表示法:第二种表示法:
4.3.4 x:Array
x:Array的作用是通过它的Item属性向使用者暴露一个类型已知的ArrayList实例。
ArrayList内成员类型由x:Array的Type指明。
WPF中把包含数据的对象称为数据源(Data Source)
把一个x:Array实例作为数据源提供给一个ListBox示例代码:
添加引用:xmlns:sys="clr-namespace:System;assembly=mscorlib"代码: Tim Tom Victor
例子具体内容见P43
4.3.5 x:Static
x:Static的功能是在XAML文档中使用数据类型的static成员
例子见P44
如果一个程序需要国际化支持,一般会把需要显示的字符串保存在一个资源类的static属性中,所以支持国际化程序的UI中对x:Static的使用非常频繁
4.4 XAML 指令元素
XAML指令元素有两个:
x:Code
x:XData
x:Code的作用是在XAML中嵌入C#代码,一般不会使用
x:XData是一个专用标签
WPF中把包含数据的对象称为数据源
用于把数据源中的数据提供给数据使用者的对象称为数据提供者(Data Provider)
XmlDataProvider用于提供XML化的数据
如果想要在XAML里声明一个带有数据的XmlDataProvider实例,那么XmlDataProvider实例的数据要放在x:XData标签的内容里。
作者:norman1981
链接://www.greatytc.com/p/a552b3f2c7af
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。