WPF Unleashed Chapter 2:XAML Demystified 翻译(第一部分)

 

       声明: 本译文仅供学习讨论,禁止用于商业用途,否则后果自负
                  

  我们在第一章里提到了XAML。XAML是一种很重要的语言,它可以将图形设计与开发工程很好的集成到一起。不管你是不是要进行图形设计的工作,都必要熟悉XAML语言.原因如下:

  •     XAML可以很容易地展现用户界面和物体的层次。
  •     使用XAML时推荐将前台的展现代码和后台的逻辑代码分离。这样构建出的程序有很好的可维护性。即使你是自己单独开发也应该这样做
  •     可以直接将XAML代码复制到XamlPad工具中(SDK提供的一个工具),无需编译即可显示结果
  •    所有WPF相关的工具都会用到xaml

  所以本章将深入介绍XAML的机制和语法,并提供相关代码.如果掌握了这些背景知识,不但有利于理解后面章节的代码示例,而且还能理解设计每个API的原因

XAML定义

  XAML是比较简单的声明性编程语言,可以构造和初始化.NET对象。.NET Framework 3.0可以解析和编译XAML,并提供一个单独的插件,可以在ie内浏览xaml文件。

   XAML实际上是一种.NET 的API.所以不要将它和HTML,Scalable Vector Graphics(SVG)或其他格式化语言进行比较。XAML是基于XML语法的,它也有自己的关键字,不能随意定义元素。所以 不能脱离WPF框架而谈XAMl,就像不能只说C#而不说.NET一样。

  XAML和WPF之间的关系可能会让人很困惑。首先声明的是XAML和WPF是相互独立的。虽然XAML最初是为WPF设计的,但由于其天然的多用性,XAML也应用在其他技术上(例如WF).甚至只要愿意,可以将XAML应用到任何.NET技术上。XAML的所有功能都可以由.NET语言代替,但反之则不行。我们完全可以用.NET语言代替XAML来编写WPF程序,但由于XAML本身具有很多的优点,所以很少会出现不使用XAML的情况

   元素和属性
 XAML规范定义了自身和.NET命名的空间,类型,属性,事件的映射规则,并对应到了xml的命名空间,元素和属性。下面分别使用XAML和c#声明了一个WPF的Button控件,

XAML:
<Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
Content=”OK”/>

C#:
System.Windows.Controls.Button b = new System.Windows.Controls.Button();
b.Content = “OK”;

  虽然两段代码是等效的,但只有那段xaml的文件可以被ie浏览:你会看到Button控件填充满了整个浏览器(如 2.1)

FIGURE 2.1 A simple WPF Button declared
in a .xaml file.

在XAML中声明元素和在.NET中实例化相应对象的效果是相同的。同样地,XAML中的属性和事件也都会在.NET中有所对应。下面的代码用XAML和C#设置了Button的Content属性并注册了Click事件。 
XAML:
<Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
Content=”OK” Click=”button_Click”/>

C#:
System.Windows.Controls.Button b = new System.Windows.Controls.Button();
b.Click += new System.Windows.RoutedEventHandler(button_Click);
b.Content = “OK”;

  上面的代码需要名为button_Click的方法。也就是说XAML无法再像图 2.1那样正确显示了。我们将在后面的"Compilation: Mixing XAML with Procedural Code"演示XAML和代码协同工作。注:XAML和c#一样区分大小写。

 

DIGGING DEEPER

                                                Order of Property and Event Processing
      在运行时,XAML中设置的事件处理会先于属性“挂”到元素上(除了Name属性,Name属性在对象被构造后就会立即为对象设置上去,本章的结尾将会介绍Name属性)这样就保证了当属性值发生变化时相应的事件也会触发。
      至于多个属性之间被设置的顺序(或事件),这决定于各个属性/事件在XAML的顺序。 

命名空间

  现在最神秘的地方恐怕就是之前XAML示例中的命名空间"http://schemas.microsoft.com/winfx/2006/xaml"是如何映射到.NET的System.Windows.Controls命名空间。实际上这种映射是在WPF程序集中使用多个XmlnsDefinitionAttribute的一个硬编码行为。
   XAML文件中的根元素至少需要指定一个命名空间来限定自身或子元素。当然,也可以在为元素或子元素添加多个命名空间,只不过这些命名空间的前缀必须唯一!下面的例子在第二个命名空间前加入了前缀"x"(使用xmlns:x来区别之前的xmlns)

  xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

 上面的xaml命名空间对应的.NET的System.Windows.Markup命名空间,同时也定义了一些编译和解析的指令。这些指令一般是XML元素的属性,和XAML元素的属性有些相像,但实际上并不是。本章的”XAML Keywords“部分会提供关键字列表,您可以在那里查阅相关的信息

   使用"http://schemas.microsoft.com/winfx/2006/xaml/presentation"作为默认的命名空间,而将用x作为前缀的"http://schemas.microsoft.com/winfx/2006/xaml"作为第二命名空间不过是约定俗成。这有些像在c#中使用"using System;"指令.您也可以自己写下面这样一个xaml文件,效果实际上是相同的:

<WpfNamespace:Button
xmlns:WpfNamespace=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
Content=”OK”/>

  考虑到代码的可读性,第一个命名空间不要使用前缀,其余的命名空间应尽量使用简短的前缀。

  DIGGING DEEPER
XAML的"http://schemas.microsoft.com/winfx/2006/xaml/presentation" 命名空间对应的.NET的命名空间:
. System.Windows
. System.Windows.Automation
. System.Windows.Controls
. System.Windows.Controls.Primitives
. System.Windows.Data
. System.Windows.Documents
. System.Windows.Forms.Integration
. System.Windows.Ink
. System.Windows.Input
. System.Windows.Media
. System.Windows.Media.Animation
. System.Windows.Media.Effects
. System.Windows.Media.Imaging
. System.Windows.Media.Media3D
. System.Windows.Media.TextFormatting
. System.Windows.Navigation
. System.Windows.Shapes
  由于这是一个"多对一"的映射,所以要避免引用位于不同命名空间下的具有相同名称的类。

属性元素 (Property Elements)

   本书的第一章曾经提到:元素之间的相互组合是WPF的一大特色。图2.1中的Button已经说明了这一点。实际上Button中内容并不仅仅限于文本,还可以放置其他任意内容。下面的代码就绘制了一个录音机的停止按钮:

System.Windows.Controls.Button b = new System.Windows.Controls.Button();
   System.Windows.Shapes.Rectangle r = new System.Windows.Shapes.Rectangle();
   r.Width = 40;
   r.Height = 40;
   r.Fill = System.Windows.Media.Brushes.Black;
   b.Content = r; // Make the square the content of the Button

 Button的Content属性的类型为System.Object,可以对其赋值任意类型。上面的代码将一个40*40大小的矩形赋值给Button。效果如图2.2

  上面的代码相当简洁,那么怎样用XAML中的属性完成呢?怎样才能构建上面c#代码那样的矩形的字符串然后赋值给Content属性呢。实际上并不需要构建字符串,XAML提供一套为复杂属性赋值的语法:属性元素(property elements). 代码如下:

   <Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”>
     <Button.Content>
      <Rectangle Height=”40” Width=”40” Fill=”Black”/>
     </Button.Content>
  </Button>

  上面的代码中没有使用xml属性(attribute)给Content属性赋值,而是使用了一个xml元素。Button.Content不是对象元素(object elements)而是一个属性元素(property elements).属性元素附属于对象元素,格式为"类型名称.属性名称"(TypeName.PropertyName),并且不能再包含属性(attribute)

    属性元素不仅可以用于复杂属性的赋值,还可以用于简单类型的属性赋值。下面的代码分别用属性(attributes)和属性元素两种方式为Button控件的Content属性和Background属性赋值,两者是等效的。


  attribute

   <Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
Content=”OK” Background=”White”/>

  property elements

   <Button xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”>
   <Button.Content>
           OK
   </Button.Content>
   <Button.Background>
        White
   </Button.Background>
  </Button>


  

WPF Unleashed Chapter 2:XAML Demystified 翻译(第二部分)

posted on 2007-06-14 14:44  stswordman  阅读(5453)  评论(22编辑  收藏  举报