《深入浅出WPF》学习总结之XAML标签语言二
x名称空间
“x名称空间”的这个X是映射XML名称空间时给他取的名字(如果用的是字母y,那他就叫“y名称空间了”),x名称空间里的成员(x.name、x.class)是专门给XAML编译器看的、用来引导XAML编译器把XAML代码编译成CLR代码的。大凡包含XAML代码的WPF程序都需要引用xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"命名空间
x命名空间里都有什么
x名称空间映射的是xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml",他所包含的类均与解析XAML语言相关,所以也可以称它"XAML"名称空间,与C#语言一样,XAML也有自己的编译器。XAML语言会被解析并编译,最终形成微软中间语言存储在程序集中。在解析和编译XAML语言过程中,我们经常需要告诉编译器一些重要的信息,比如XAML代码的编译结果应该与哪个C#代码的编译结果合并、使用XAML声明的元素是public还是privated访问级别等等。这些让程序员能够与XAML编译器沟通的工具就存放在x名称中间中。
x名称空间中包含的工具
名称 | 种类(在XAML中出现的形式) |
x:Array | 标记扩展 |
x:Class | Attribute |
x:ClassModifier | Attribute |
x:Code | XAML指令元素 |
x:FieldModifier | Attribute |
x:Key | Attribute |
x:Name | Attribute |
x:Null | 标记扩展 |
x:Shared | Attribute |
x:Static | 标记扩展 |
x:Subclass | Attribute |
x:Type | 标记扩展 |
x:TypeArguments | Attribute |
x:Uid | Attribute |
x:XData | XAML指令元素 |
它们可以被分为Attribute、标记扩展和XAML指令元素三类
x名称空间中的Attribute
前面我们已经知道,Attribute与Property是两个层面的东西。Attribute是语言层面的东西,是给编译器看的,Property是面向对象层面的东西,是给编程逻辑用的,而且一个XAML标签的Attribute里大部分对应着对象的Property。在使用XAML编程的时候,如果你想给它加上一个特殊的标记从而影响XAML编译器对他的解析,这时候就需要额外为他添加一些Attribute了,比如,你想告诉XAML编译器将编译结果与哪个C#编译的类合并,这时候就必须为这个标签添加x:Class="目标类名"这样一个Attribute已告知XAML编译器。x:Class这个Attribute并不是对象的成员,而是我们把它从x名称空间里拿出来硬贴上去的x:Class
这个Attribute的作用是告诉XAML编译器将XAML标签的编译结果与后台代码中指定的类合并。
在使用x:Class时必须遵循以下要求:
1、这个Attribute只能用于根节点
2、使用x:Class的根节点的类型要与x:Class的值所指示的类型保持一致
3、x:Class的值所指示的类型在声明时必须使用partial(部分类)关键字。
x:ClassModifier
这个Attribute的作用在告诉XAML编译由标签编译生成的类具有怎用的访问级别,在使用这个标签的时候需要注意:
1、便签必须具有x:Class Attribute。
2、x:ClassModifier的值必须与x:Class所指示类的访问控制级别一致。
x:Name
x:Name的作用有两个
1、告诉XAML编译器,当一个标签带有x:Name时除了为这个标签生成对应实例外还要为这个实例声明一个引用变量,变量名就是x:Name的值
2、将XAML标签所对应对象的Name属性(如果有)也设为x:Name的值,并把这个值注册到UI树上,方便查找使用
那么在XAML代码中应该使用Name还是x:Name呢?Name属性定义在FrameworkElement类中,这个类是WPF控件的基类,所以所有的WPF控件都具有Name这个属性。当一个元素具有Name属性时,你使用Name或x:Name效果是一样的,比如<Button x:Name="btn"/>和<Button Name="btn"/>,XAML编译器的动作都是声明为btn的Button类型变量并引用一个Button类型实例,而且此实例的Name属性也为btn。此时,Name和x:Name是可以互换的,只是不能同时出现在一个元素中。对于那些没有Name属性的元素,为了在XAML声明时也创建引用变量在C#代码中访问,我们就只能使用x:Name。因为x:Name的功能涵盖了Name属性的功能,所以全部使用x:Name以增强代码的统一性和可读性
x:FieldModifier
在使用x:Name后,XAML标签对应的实例就具有了自己的引用变量,而且这些引用变量都是类的字段。既然是类的字段就免不了要关注一下它们的访问级别。默认情况下,这些引用变量都是类的字段。既然是类的字段就免不了需要访问级别。默认情况下,这些字段的访问级别都是按照面向对象的封装原则被设置成了internal。在编程的时候,有时候我们需要从一个程序集访问另一个程序集中窗体的元素,这时候就需要把访问控件的引用变量改为public级别,x:FieldModifier就是用来在XAML里改变引用变量访问级别的。值得注意的是,因为x:FieldModifier是用来改变引用变量访问级别的,所以使用x:FieldModifier的前提是这个标签同时也使用x:Name,不然何来的引用变量呢。
x:Key
最自然的方式莫过于使用“key-value”对的形式了。在XAML文件中,我们可以把很多需要多次使用的内容提取出来放在资源字典(Resource Dictionary)里,需要使用这个资源的时候就用它的Key把它检索出来。x:Key的作用就是为资源贴上用于检索的索引,在WPF中,几乎每个元素都有自己的Resources属性,这个属性是个“Key-Value”式的集合,只要把元素放在这个集合,这个元素就成为资源字典中的一个条目,当然,为了能够检索到这个条件,就必须为它添加x:Key。资源(Resources)在WPF只非常重要,需要重复使用的XAML内容,如Style、各种Template和动画等都需要放在资源里。
<Window x:Class="WpfApp2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="Demo" Height="200" Width="300">
<Window.Resources>
<sys:String x:Key="myString">Hello World</sys:String>
</Window.Resources>
<StackPanel Orientation="Vertical">
<TextBox Margin="10" Text="{StaticResource ResourceKey=myString}" x:Name="txtSrc"></TextBox>
<TextBox Margin="10" x:Name="txtDes"></TextBox>
<Button Margin="10" Click="Button_Click">Show</Button>
</StackPanel>
</Window>
在XAML中使用String类,我们用xmlns:sys="clr-namespace:System;assembly=mscorlib"引用了mscorlib.dll,并把其中的System命名空间映射为XAML中的sys命名空间。然后,我们使用属性标签语法向Window.Resources里添加了一个字符串,并把它的x:Key设置为myString。窗体的StackPanel里包含了两个TextBox和一个Button,在为第一个TextBox设置Text属性时,我们用到了myString这个资源,因此,程序一运行我们就可以看到第一个TextBox显示了资源字符串的值
资源不但可以在XAML中访问,在C#中也可以访问下面是Button.Click事件处理器:
private void Button_Click(object sender, RoutedEventArgs e)
{
var myString = this.FindResource("myString") as string;
txtDes.Text = myString;
}
调用一个拥有Resources属性的对象的FindResource方法就可以在他的资源字典里检索资源,检索到资源之后再把它恢复成正确的数据类型就可以使用了。单击按钮之后,就可以看见TxtDes文本框显示出同样的字符串。
x:Shared
在使用x:Key时候我们知道,一旦我们把某些对象当作资源放进字典后就可以把它们检索出来重复使用,那么,每当我们检索到一个对象的时候,我们得到的究竟是同一个对象呢,还是这个对象的多个副本呢?那就的看我们给x:Shared赋什么值了,x:Shared一定要与x:Key配合使用,如果x:Shared的值为True,那么每次检索到这个对象的时,我们得到的都是同一个对象,否则如果x:Shared的值为False,每次我们检索到这个对象时,我们得到的都是这个对象的一个新副本。XAML编译器会为资源隐藏添加x:Shared="True",也就是说,默认情况下我们得到的都是同一个资源
x命名空间中的扩展标记
标记扩展(Markup Extension)实际上就是一些MarkupExtension类的直接或者间接派生类。x名称空间中就包含有一些这样的类,所以常称它们为x名称空间内的标记扩展。
x:Type
x:Type的值是一个数据类型的名称,一般情况下,我们在编程中操作的时数据类型的实例的引用,但有时候我们也会用到数据类型本身。当我们在XAML中想表达某个数据类型时就需要使用x:Type标记扩展,比如某个类的一个属性,它的值要求时一种数据类型,当我们在XAML为这个属性赋值就要使用x:Type。
首先我们创建一个Button派生类
class MyButton:Button
{
public Type UserWindowType { get; set; } protected override void OnClick()
{
base.OnClick(); var winType = Activator.CreateInstance(UserWindowType) as Window;
if (winType == null)
return;
winType.Show();
}
}
这个类具有一个Type类型的属性,即UserWindowType ,我们需要把一种数据类型赋值给他,同时这个类还重写了基类的OnClick事件,除了可以像基类那样触发Click事件外,还会使用UserWindowType 所存储的类型创建一个实例,如果这个类型实例时Window类(或其派生类)的实例,那么就把这个窗体显示出来
然后我们在项目中添加一个名为MyWindow的Window派生类。
<Window x:Class="WpfApp2.MyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="MyWindow" Height="200" Width="300">
<StackPanel Orientation="Vertical" x:Name="mainPanel" >
<TextBox Margin="10"></TextBox>
<TextBox Margin="10"></TextBox>
<Button Margin="10">ClickMe</Button>
</StackPanel>
</Window>
最后,把自定义按钮添加到主窗口的界面上,并把MyWindow作为一种数据类型赋值给MyButton.UserWindowType 属性
<Window x:Class="WpfApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="Demo" Height="200" Width="300">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<local:MyButton Width="200" UserWindowType="{x:Type TypeName=local:MyWindow}">Show</local:MyButton>
</Grid>
</Window>
注意:因为MyButton和MyWindow这两个自定义类都包含在当前项目的名称空间中,所以把当前项目的名称空间引用进来并用local前缀映射,所以在使用MyButton和MyWindow时也要为它们加上local前缀
编译并运行程序,单击主窗体上的按钮,自定义窗体就会显示出来。我们还可以多写几个自定义窗体类来扩展这个程序,到时候只需要在XAML里面更换UserWindowType 的值就可以了。
x:Null
有时候我们需要对一个属性赋一个空值,在C#语言里,使用null关键字来表示空值,在XAML里用来表示空值的是x:Null。大多数时候我们不用显式的为一个属性赋null值,但如果一个属性具有默认值而我们又不需要这个默认值时就需要显式的设置null值了。
<Window x:Class="WpfApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="Demo" Height="200" Width="300">
<Window.Resources>
<Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
<Setter Property="Width" Value="60"></Setter>
<Setter Property="Height" Value="30"></Setter>
<Setter Property="Margin" Value="10"></Setter>
</Style>
</Window.Resources>
<StackPanel Orientation="Vertical">
<Button>Hello</Button>
<Button>Hello</Button>
<Button Style="{x:Null}">Hello</Button>
</StackPanel>
</Window>
上面的例子把一个Style放在了Window的资源里并把它的x:Key 和 TargetType都设置成了Button类型,这样UI上的所有Button控件都默认的被套用了这个Style,除了出后一个Button因为它显式的把Style设置为了x:Null
x:Array
x:Array的作用就是通过他的Items属性向使用者暴露了一个类型已知的ArrayList实例,ArrayList内成员的类型由x:Array的Type指明,下面这个例子把一个x:Array当作数据源向一个ListBox提供数据
<Window x:Class="WpfApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="Demo" Height="200" Width="300">
<Grid>
<ListBox>
<ListBox.ItemsSource>
<x:Array Type="sys:String">
<sys:String>Hello World</sys:String>
<sys:String>Hello Simple</sys:String>
<sys:String>Hello C#</sys:String>
</x:Array>
</ListBox.ItemsSource>
</ListBox>
</Grid>
</Window>
这样,在解析<x:Array>标签的时候编译器会生成调用AddChild方法的代码把<x:Array>标签的子元素逐个添加到x:Array实例的Item里
x:Static
x:Static是一个很常用的标记扩展,它的功能是在XAML文档中使用数据类型的static成员。因为XAML不能编写逻辑代码,所以使用x:Static访问的static成员一定是数据类型的属性或字段。
<Window x:Class="WpfApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="{x:Static local:MainWindow.WindowTitle}" Height="200" Width="300">
<StackPanel>
<TextBlock FontSize="30" Text="{x:Static local:MainWindow.ControlContent}"></TextBlock>
</StackPanel>
</Window>
XAML指令元素
XAML指令元素有两个
x:Code
他的作用就是可以包含一些本应放置在后置代码中的C#代码,这样做的好处是不用把XAML代码和C#代码分置在两个文件中,但若不是遇到某些极端环境请前往别这么写,这样做最大的问题就是代码不好维护,不易调试
x:XData
x:XData是一个专用标签,WPF中把包含数据的对象称为数据源,用于把数据源中的数据提供给数据使用者的对象被称为数据提供者(Data Provider)。WPF类库中包含多种数据提供者,其中有一个类叫XmlDataProvider,专门用于提供XML化的数据,如果想在XAML总声明一个带有数据的XmlDataProvider实例,那么XmlDataProvider实例的数据就要放在x:XData标签的内容里
《深入浅出WPF》学习总结之XAML标签语言二的更多相关文章
- 《深入浅出WPF》学习总结之XAML标签语言一
一.XMAL概览 1.XAML在桌面开发及富媒体网络程序的开发中扮演了HTML+CSS+JS的角色. 2.XAML可以将UI和逻辑代码分离,降低耦合度. 3.XAML是一种单纯的申明形语言 4.XAM ...
- WPF学习笔记1——XAML之1
参考文献: http://msdn.microsoft.com/zh-cn/library/ms752059(v=vs.110).aspx <Pro WPF 4.5 in C# > 一.X ...
- WPF学习笔记——认识XAML
Extensible Application Markup Language,XAML是一种声明性标记语言. 一.XAML语法概述 1,与XML类似,用尖括号标记元素 <StackPanel&g ...
- WPF学习笔记2——XAML之2
三.事件处理程序与代码隐藏 例如,为一个Page添加一个Button控件,并为该Button添加事件名称Button_Click: <Page xmlns="http://schema ...
- WPF学习一:XAML的资源(Resources)结构
一个初学者,把知识做个积累,如果有不对的地方,还请高手指出,谢谢! 先看一段代码:(下面是以Window WPF进行讲解,如果是Web 的话就把<Window改为<Page 而如果是 Us ...
- WPF学习笔记 - 在XAML里绑定
Binding除了默认构造函数外,还有一个可以传入Path的构造函数,下面两种方式实现的功能是一样的. <TextBlock x:Name="currentFolder" D ...
- JavaWeb学习总结-12 JSTL标签语言
一 JSTL JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能. JSTL支持通用的.结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签. 除了 ...
- 《深入浅出WPF》 学习笔记
<深入浅出WPF> 序言 1. 什么是WPF 2. 为什么要学习WPF 第一章 XAML概览 1. XAML是什么? 2. XAML有哪些优点 第二章 从零起步认识XAML 1. 新 ...
- 4 WPF学习---系统的学习XAML语法
转载:http://blog.csdn.net/fwj380891124/article/details/8093001 1,XAML文档的树形结构: UI在用户眼里面是个平面结构.如下图所示,在用户 ...
随机推荐
- dockerfile制作笔记
dockerfile语法格式: FROM: 基础镜像(就是在什么镜像上面做) MAINTAINER: 镜像创建者信息(作者的信息) EXPOSE: 开放的端口 ENV: 设置变量 ...
- 刷PTA这一周的感悟
在慕课上报名了浙江大学的<数据结构>这门课,主讲人陈越老师,何钦铭老师,两位老师讲的很好,课后有配套的PTA可以用来做题,练习. 最近在PTA上刷题,发现自己代码实现能力是真的差劲,一开始 ...
- 043:Django使用原生SQL语句操作数据库
Django使用原生SQL语句操作数据库 Django配置连接数据库: 在操作数据库之前,首先先要连接数据库.这里我们以配置 MySQL 为例来讲解. Django 连接数据库,不需要单独的创建一个连 ...
- 【NOIP2016提高组A组7.16】第三条跑道
题目 数据范围 分析 时限5000ms. 我们注意到\(a_{i}初始值以及x小于等于600且非零\) 也就是说,\(a_{i}\)的质因数一定小于600,而600以内的质因数只有109个. 那么考虑 ...
- zrender笔记----(数字Number组件)出现的问题和解决办法
1.期望的效果是这样子的(这也是最终结果): 2.开始是用json假数据,开始没考虑null的问题,导致在判断传值处,判断有误. 导致在对接接口时,凌乱了,后来修改了下变成后面图C的逻辑,json数据 ...
- Javascript获取页面元素相对和绝对位置
制作网页的过程中,你有时候需要知道某个元素在网页上的确切位置. 下面的教程总结了Javascript在网页定位方面的相关知识. 一.网页的大小和浏览器窗口的大小 首先,要明确两个基本概念. 一张网页的 ...
- MySQL 数据库慢查询日志分析脚本
这个脚本是基于pt-query-digest做的日志分析脚本,变成可视化的格式. 目录结构是 ./mysql_data/log./mysql_data/log/tmp./slow_query # co ...
- Java——容器(List)
[List接口]
- XXX is not a function
今天,一个以前的小伙伴跟我说他遇到了一个问题,调试了将近两天(这家伙一开始不打算干程序员,跑去干了两个月销售,现在又想回来写代码了,所以就自己折腾一个demo,免得面试的时候被问住) 我把他的代码从头 ...
- WWDC2017-whats_new_in_safari_view_controller
最后更新: 2017-08-08 官方地址: https://developer.apple.com/videos/play/wwdc2017/225/ WWDC2017中,对SafariViewCo ...