WPF XAML 从零开始认识XAML

来自:http://blog.csdn.net/aoshilang2249/article/details/44158403


 剖析最简单的XMAL代码:

[html] view plain copy
  1. <Window x:Class="MyFirstApplication.MainWindow"  
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.         Title="MainWindow" Height="350" Width="525">  
  5.     <Grid>  
  6.           
  7.     </Grid>  
  8. </Window>  

        花花绿绿一大片,还有两个像主页地址的东西....它们都是些什么呢,让我们一个个来分析。

   XAML是由XML派生出来的语言,所以有很多在XML中的概念在XAML中是通用的。比如使用标签声明一个元素(每一个元素对应内存中的一个对象)时,需要使用起始标签<tab>和结束标签</tag>,夹在起始标签和终止标签中的XAML代码表示隶属于这个标签的内容。如果没有什么内容隶属于这个标签,则这个标签称为空标签,可以写为<tag/>


    为了表示同类标签中的某个标签的与众不同,可以给它的特征(Attribute)赋值。为特征赋值的语法如下:
    非空标签:<tag Attribute1=value1 Attribute2=value2>content</tag>
    空标签<tag Attribute1=value1 Attribute2=value2/>

    在这里有必要把Attribute和Property仔细地辨别一下。

    这个词的混淆由来已久,混淆的主要原因是大多数的中文译文里即把Attribute译为“属性”,也把Property译为“属性”,其实,这两个词表示的不是同一个层面上的东西。


    Property属于面向对象的范畴。在使用面向对象编程的时候,常常需要对客观事物进行抽象,在把抽象出来的结果封装成类,类中用来表示事物状态的成员就是Property。比如要编写一个模拟赛车的游戏,那么必不可少的就是要对现实的赛车进行抽象,现实中汽车会带很多数据,但是游戏中可能只关心它的长度,宽度,高度,重量,速度等有限的几个数据,同时,还会把汽车的加速,减速等行为提取出来用算法进行模拟,这个过程就是属于抽象(结果是Car这个类)。显然,Car.Length,Car.Height,Car.Weight等表达的是当前汽车所处的一个状态,而Car.Accelerate()、Car.Break()表达的是汽车能做什么。因此,Car.Length,Car.Height就是Property的典型属性,是针对对象而言的。将Property译为“属性”也很贴切,总之一句话:Property属性是针对对象而言的。


    Attribute则是编程语言文法层面的东西。比如有两个同类语法的元素A和B,为了表示A与B不完全相同或者A与B的用法上有些区别,这时候就要针对A和B加一些Attribute。也就是说Attribute只与语言层面上的东西有关,与抽象出来的对象没有什么关系。因为Attribute是为了表示“区分”的。所以它译为“特征”。C#中的Attribute就是这种应用的典型例子,我们可以为一个类添加Attribute,这个类里面有很多Property(属性)。显然,Attribute只用来影响类中程序中的用法,而Property 则对应着抽象对象身上的性状,根本不是一个层面上的东西。


    习惯上,英语中把标签式语言中表示一个标签特征的“名----值”对称做Attribute。如果恰好有在使用一种标签式语言做面向对象编程,这两个概念就有可能混在一起了。实际上,使用能够使用面向对象编程的标签式语言只是把标签和对象做了一个映射-----针对标签还是叫做Attribute,针对对象还是叫做Property,仍然不是一个层面上的东西。而且,标签的Attribute不是和对象的Property一一映射的,往往一个标签对于的Atrribute大于他所映射对象的Property。


    因为XAML是用来在UI上绘制控件的,而控件本身就是面向对象的抽象产物,所以XAML标签中的Atrribute有一大部分和它对应他的对象的Property是一一对应的。当然,这还意味着标签中的Atrribute并不对应它所代表对象的Property。


    明白了XAML的格式以及Atrribute和Property之间对应的关系,对上面的代码可谓是一目了然。它的总体结构是一个Window标签内包含一个Grid标签(或者说Grid标签是Window标签的内容),所代表的内容是一个Window对象里面包含一个Grid对象。


    XAML是一种声明式语言,当你看见一个标签,就证明你声明了一个对象,对象之间的关系要么是并列,包含全都体现在标签的关系上。
下面的代码就是<Window>标签的Atrribute。

[html] view plain copy
  1. x:Class="MyFirstApplication.MainWindow  
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation  
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml  
  4. Title="MainWindow" Height="350" Width="525"  

     其中Title、Width、Height一看就知道和Window的Property对象对应的。中间两行(即两个xmlns)是在声明名称空间。最上面一行是在使用名为class的Attribute, 这个Attribute来自于X:前缀所对应的名称空间 。下面仔细解释。


    前面已经说过,XMAL语言是从XML语言派生而来的。XML有一个功能就是可以在XML文档的标签内使用xmlns特征来定义名称空间(NameSpace),XML也就是XML--NameSpace的缩写。定义名称空间的好处就是,当来源不同的类重名时,可以使用名称空间加以区分。xmlns特征的语法如下:

[html] view plain copy
  1. xmlns[:可选的映射前缀]=“名称空间”  

      xmlns后可以跟一个可选的映射前缀,之间用冒号隔开。如果没有写可选映射的前缀,那就意味着所有来自这个名称空间的所有标签都不用加这个前缀,这个没有映射的命名空间称为“默认的命名空间”,默认名称空间只能有一个,而且应该选择其中使用最频繁的名称空间来作为默认命名空间。在上面的例子中,<Window>和<Grid>来自于第二行声明的默认命名空间,而第一样的CLASS特征则来来自于三行的中x:前缀对应的名称空间。这里可以做一个有趣的小实验:如果给第二行声明的名称空间加一个前缀,例如n,那么代码必须要改成一下形式编译才能通过:

[html] view plain copy
  1. <n:Window x:Class="WpfApplication2.Window2"    
  2.         xmlns:n="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
  4.         Title="Window2" Height="300" Width="300">    
  5.     <n:Grid>    
  6.             
  7.     </n:Grid>    
  8. </n:Window>  

      XAML中引用外来程序集和其中.NET名称空间的语法和C#是不一样的。在C#中,如果想使用System.Windows.Control名称空间内的Button类,需要先把包含System.Windows.Control名称空间的程序集PresentationFramework.dll添加引用到项目中,然后再用C#代码顶部写上一句:using System.Windows.Control;。

在XAML中做同样的事情也需要添加对程序集的引用,然后再在根元素的起始标签中写上一句:xmlns:c="clr-namespace:System.Windows.Control;assembly=PresentationFramework"。c是映射的前缀,换成其它字符串也可以。因为button来自前缀为c的命名空间,所以在使用button的时候就要使用<c:Button>....</c:Button>。

    xmlns:c="clr-namespace:System.Windows.Control;assemble=PresentationFramework",这么长的一串字符串看上去的确有点恐怖,但不用担心,VS中有自动提示功能。
在VS自动提示的顶部,你会看到几个像网站地址的几个名称空间,其中就包含例子代码中的那两行。为什么名称空间看上去像一个网站地址呢。其实把它copy到浏览器地址栏尝试跳转也不会打开网页。这里只是XAML解释器的一个硬性编码(hard-coding),只要见到这些固定的字符串,就会把一系列的程序集和程序集中包含的名称空间引入进来。


    默认引入的这两个名称空间格外的重要,它们对应的程序集和.net名称空间如下:

    http://schemas.microsoft.com/winfx/2006/xaml/presentation对应:

[html] view plain copy
  1. System.Windows;  
  2. System.Windows.Automation;  
  3. System.Windows.Control;  
  4. System.Windows.Control.Primitives;  
  5. System.Windows.Data;  
  6. System.Windows.Document;  
  7. System.Windows.Forms.Intergration;  
  8. System.Windows.Ink;  
  9. System.Windows.Input;  
  10. System.Windows.Media;  
  11. System.Windows.Media.Animation;  
  12. System.Windows.Media.Effects;  
  13. System.Windows.Media.Imaging;  
  14. System.Windows.Media.Media3D;  
  15. System.Windows.Media.TextFormmatting;  
  16. System.Windows.Navigation;  
  17. System.Windows.Shapes;  

     也就是说你可以在XAML中可以直接使用这些CLR名称空间下的类型(因为默认XML名称空间前没有前缀)。
    

    http://schemas.microsoft.com/winfx/2006/xaml则对应一些与XAML语法和编译相关的CLR名称空间, 使用这些名称空间中的类型需要加上前缀x,因为它们被映射到x的XML名称空间中。


    从这两个名称空间的名字和它所对应的.NET程序集上,这个不难看出,第一个空间名称对应的是绘制UI相关的程序集,是表示(Presentation)层面上的东西;第二个名称空间则对应着XAML解析处理相关的程序集,是语言层面上的东西。


     最后让让我回到最初的代码。你可能会问:在XAML里面有x:Class="MyFirstApplication.MainWindow",在MainWindow.xaml.cs里面也声明了MainWindow这个类,难道他们不会冲突吗?仔细看看MainWindow.xaml.cs中MainWindow的声明就知道了----在声明的时候使用的是partial关键字,这样,这样由XAML中解析成的类和C#文件里面定义的部分就合二为一了,正是由于这种partial机制,我们可以把逻辑代码留在.cs文件里,用C#语言来实现,而把那些声明及布局UI元素的代码分离出去,实现UI和逻辑分离,并且,用于绘制UI的代码(如声明控件类型的字段,设置它们的外观和布局等)也不必再使用C#语言,使用XAML和XAML编辑工具就可以轻松搞定。


参考《深入浅出WPF》


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458581.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言题库3

143. 枚举元素本身由系统定义了一个表示序号的数值&#xff0c;从0 开始顺序定义为0&#xff0c;1&#xff0c;2…。如在weekday中&#xff0c;sun值为0&#xff0c;mon值为1&#xff0c; …,sat值为6。 main(){  enum weekday  {   sun,mon,tue,wed,thu,fri,sat  } a,b…

入门级----测试的执行、环境的搭建、每日构建、测试记录和跟踪、回归测试、测试总结和报告...

测试用例的准备&#xff0c;都是为了执行测试准备的。 测试环境的搭建 &#xff08;1&#xff09;测试数据&#xff1a;有些测试需要使用大批量的数据&#xff0c;例如容量测试、压力测试等。根据产品的具体测试要求&#xff0c;可能需要在数据库表插入大量的数据&#xff0c;准…

MFC读取配置文件GetPrivateProfileString

VC中 3 个主要 写入/读取配置文件ini的函数&#xff1a;bool WritePrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpString,LPCTSTR lpFileName);写入.ini文件&#xff1b;DWORDGetPrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpD…

UESTC 250 windy数 数位dp

题目链接 1 #include<bits/stdc.h>2 using namespace std;3 #define mem1(a) memset(a, -1, sizeof(a))4 #define ll long long5 int dp[20][20], digit[20], len;6 ll dfs(int len, int pre, bool fp, bool first) { //first表示前面的数是否全部为0&#xff0c; pr…

c语言面试题大全

C语言面试题大汇总 4. static有什么用途&#xff1f;&#xff08;请至少说明两种&#xff09; 1.限制变量的作用域(DL:使其只在定义的当前文件中起作用&#xff0c;static是只能由与变量在同一个文件中定义的程序存取的全局变量。也就是说使全局变量成为文件的私有变量&#…

WindowsAPI详解——GetCurrentDirectory 获得程序当前目录

每个Windows程序都有一个自己的当前目录&#xff0c;默认是程序exe文件所在的目录。系统在给程序加载动态链接库文件(DLL)时先在程序当前目录里查找要加载的DLL&#xff0c;如果在此目录下没有找到系统便会去Windows目录下查找。在这儿我们主要将如何获得程序的当前目录&#x…

20151210小问题2

1、各浏览器下 scrollTop的差异 IE6/7/8&#xff1a; 对于没有doctype声明的页面里可以使用 document.body.scrollTop 来获取 scrollTop高度 &#xff1b; 对于有doctype声明的页面则可以使用 document.documentElement.scrollTop&#xff1b; Safari: safari 比较特别&#x…

限制MySQL Binlog的传输速率

最近一台核心库备库完成恢复后打开slave&#xff0c;导致主库传送binlog&#xff0c;瞬间占满网络&#xff0c;触发故障。 为了做一些限制&#xff0c; 给mysql在发送binlog的函数(mysql_binlog_send)里每隔一段时间sleep一次&#xff0c; 增加了两个参数&#xff1a; master_s…

sprintf用法详解

printf可能是许多程序员在开始学习C语言时接触到的第二个函数&#xff08;我猜第一个是main&#xff09;&#xff0c;说起来&#xff0c;自然是老朋友了&#xff0c;可是&#xff0c;你对这个老朋友了解多吗&#xff1f;你对它的那个孪生兄弟sprintf了解多吗&#xff1f;在将各…

掌握 Ajax,第 2 部分: 使用 JavaScript 和 Ajax 发出异步请求

转http://www.ibm.com/developerworks/cn/xml/wa-ajaxintro2/ 掌握 Ajax&#xff0c;第 2 部分: 使用 JavaScript 和 Ajax 发出异步请求 在 Web 请求中使用 XMLHttpRequest 多数 Web 应用程序都使用请求/响应模型从服务器上获得完整的 HTML 页面。常常是点击一个按钮&#xff0…

Provisioning Services 7.8 入门系列教程之十一 通过版本控制自动更新虚拟磁盘

续Provisioning Services 7.8 入门系列教程之十 通过类自动更新虚拟磁盘从前两的两种更新方式可以看出&#xff0c;它们有一个共同的特点&#xff0c;即需要产生&#xff08;复制&#xff09;完成的虚拟磁盘副本&#xff0c;然后进行相关的升级操作。这两种方法在实际生产中&am…

OC面试题

什么是KVC和KVO&#xff1f; 答&#xff1a;KVC(Key-Value-Coding)内部的实现&#xff1a;一个对象在调用setValue的时候&#xff0c; &#xff08;1&#xff09;首先根据方法名找到运行方法的时候所需要的环境参数。 &#xff08;2&#xff09;他会从自己isa指针结合环境参数&…

【算法】QuickSort

快速排序&#xff0c;时间复杂度O(N*logN)&#xff0c;要能熟练掌握&#xff01; 以下主要参考http://blog.csdn.net/morewindows/article/details/6684558&#xff0c; 感谢原博主&#xff01; 该方法的基本思想是&#xff1a; 1&#xff0e;先从数列中取出一个数作为基准数。…

串口之GetCommState、SetCommState函数详解

GetCommState 读取串口设置(波特率,校验,停止位,数据位等).函数声明&#xff1a;BOOL GetCommState(HANDLE hFile,LPDCB lpDCB);GetCommState函数的第一个参数hFile是由CreateFile函数返回指向已打开串行口的句柄。第二个参数指向设备控制块DCB。如果函数调用成功&#xff0c;则…

登录失败时记住访问的地址

登录失败时记住访问的地址 使用spring MVC 访问时,在拦截器中记录访问的地址: Java代码 String path request.getRequestURI();//"/demo_channel_terminal/news/list" System.out.println("您无权访问:" path); //用于登录成功…

串口之GetCommTimeouts、SetCommTimeouts函数详解

Windows系统利用此函数获取特定的通讯设备读写时的超时参数设定&#xff0c;GetCommTimeouts函数声明如下&#xff1a;BOOL GetCommTimeouts(HANDLE hFile,LPCOMMTIMEOUTS lpCommTimeouts);GetCommTimeouts函数的第一个参数hFile是由CreateFile函数返回指向已打开串行口的句柄。…

GUN/LINUX命令之 cp mv install

1. cp命令 复制copy命令的简写 SYNOPSIS cp [OPTION]... [-T] SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY cp [OPTION]... -t DIRECTORY SOURCE... cp SOURCE DEST 后者如果是目录那么源文件就复制到文件夹里面并且保持着原来的名字&#xff1b;如果D…

Tomcat - Maven plugin: 运行找不到webapp

2019独角兽企业重金招聘Python工程师标准>>> The tomcat7-maven-plugin allows running the current project as a Web application and additional <webapps> can be specified that will be simultaneously loaded into tomcat. My project is not a Web ap…

面试题3

1. 你如何理解 iOS 内存管理 1. new alloc copy retain这些对象我们都要主动的release或者 autorelease 2. 如果是类方法创建的对象,那么系统自动释放池自动在适当的 时候会帮我们 release 3. ARC xcode 自动会帮我们人工智能的添加 release autorelease 操 作 2. C语言里的数…

基于MQTT协议进行应用开发

来自&#xff1a;http://www.cnblogs.com/secondtononewe/p/6073089.html 官方协议有句如下的话来形容MQTT的设计思想&#xff1a; “It is designed for connections with remote locations where a "small code footprint" is required or the network bandwidth i…