• [Windows8 app store开发系列教程二] XAML(2)


      上一篇博文我简单的介绍了一下xaml的概况,下面我将讲解一下具体的语法

    元素和特性

      XAML规范定义了一些规则,用于把.NET命名空间、类型、属性和事件映射为XML命名空间、元素和特性。以下面为例,它定义了一个win8的按钮,跟另一段与之功能一致的C#代码比较一下(上一篇博文里):

    下面定义了一个win8应用的按钮:

      XAML:

    <Button Content="Button" HorizontalAlignment="Left" Margin="152,87,0,0" VerticalAlignment="Top" Width="75"/>

      C#

    Button b = new Button();
    b.Content = "OK";
    b.Click += new RoutedEventHandler(button_Click);
    grid.Children.Add(b);//grid是Grid控件的name,这句话是用来把动态生成的button键显示在grid上

      虽然这两段代码功能是相同的,但如果去除掉XAML中的Click特性,你可以很快地在vs中查看XAML,还会看到一个活生生的按钮放在设计器中。而C#代码则必须要额外的代码编译方可使用。也就是说在XAML中定义一个元素(叫作对象元素)与在.NET中实例化一个对应的对象(总是使用默认的构造函数)是等价的。设置对象元素的一个特性(attribute),与设置一个同名属性(property attribute,称为属性特性)或者为一个同名事件设置一个事件处理程序(也称为事件特性),也是等价的。

    生成和事件处理的顺序

      在运行时(run-time)模式下,为任何一个XAML声明的对象设置属性之前,总要添加一些事件处理程序,这样就可以让某个事件在属性被设置时被触发,而不用担心XAML使用特性的顺序。

      至于多个属性集或添加多个事件处理程序,它们总会遵照一定顺序,即属性特性和事件属性是在对象元素中指定的。这一排序方式不会在实际应用中产生影响,因为.NET设计指南指出:类应该允许以任何顺序设置属性,添加事件处理程序也是如此。

    命名空间

      

    比较上述XAML代码示例和相应的C#代码示例,最神秘的地方在于XAML命名空间("http://schemas.microsoft.com/winfx/2006/xaml/presentation")是如何被映射到.NET命名空间(Windows.UI.Xaml.Controls;)上的。该映射及其他win8命名空间的映射是在win8程序集中硬编码完成的。

      XAML文件的根对象元素属性指定至少一个XML命名空间,用于验证自己和子元素。你可以(在根元素或子元素上)声明额外的XML命名空间,但每一个命名空间下的标识符都必须有一个唯一的前缀。例如,win8应用的XAML文件都会使用第二个命名空间加上前缀x(记作xmlns:x而不仅仅是xmlns):

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

      这是XAML语言命名空间,用于映射System.Windows.Markup命名空间中的类型,而且它也定义了XAML编译器或解析器中的一些特殊的指令。这些指令通常是作为XAML元素的特性出现的,因此,它们看上去像宿主元素的属性,但实际上并不是如此。

      我们把http://schemas.microfost.com/winfx/2006/xaml/presentation作为默认(主要)命名空间,把xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"作为次要命名空间。次要命名空间的前缀是x,这仅仅是一个规则,就像C#文件要以using System;指令开始一样。

    属性元素

      富创建是xaml的亮点之一,我们可以用Button来演示。你可以把任意内容放在Button里面,不仅限于文本,如下所示(在Button中嵌入了一个图片来做一个图片按钮):

    <Button HorizontalAlignment="Left" Margin="539,118,0,0" VerticalAlignment="Top">
                <Button.Content>
                    <Image Source="oureda.png" Height="100" ></Image>
                </Button.Content>
    </Button>

    效果图如下:

    当然正如我们所说,还可以使用c#编写后台代码达到相同的效果:

    Image i = new Image();
    i.Height = 100;
    Button b = new Button();
    i.Source = new BitmapImage(new Uri("ms-appx:///oureda.png"));
    b.Content = i;
    grid.Children.Add(b);

      Content属性被设置为一个XML元素而不是XML特性,Button.Content中的句点用于区分对象元素(object element)与属性元素(property element)。它们总会以“类型名,属性名TypeName.PropertyName”的形式出现,总会包含在“类型名”对象元素中,但它们没有属于自己的特性。

      属性元素语法也可以用于简单的属性值。下面的Button使用特性设置了两个属性,它们是Content和Background:

     <Button Content="Button" Background="Yellow"/>

      这等同于使用元素设置该Button的两个相同的属性:

    <Button>
      <Button.Content>
        
    OK   </Button.Content>   <Button.Background>
        Yellow
      </Button.Background>
    </Button>

    类型转换器

      上例XAML文件中的“Yellow”是如何转化到C#中的Windows.UI.Xaml.Media.Brush类型的呢?这个示例提供了一些如何使用字符串设置XAML属性的细节,这些属性的类型即不是System.String,也不是System.Object。在这种情况下,XAML解析器或编译器必须寻找一个类型转换器,该转换器知道如何将一个字符串表达式转换为一种想要的数据类型。WPF提供了许多常用数据类型的类型转换器,如Brush、Color、FontWeight、Point等,它们都派生自Type-Converter的类(如BrushConverter、ColorConverter等),你也可以为自定义的数据类型写类型转换器。与XAML语言不同,类型转换器通常支持不区分大小写的字符串。

      如果没有Brush类型转换器,你就必须使用属性元素语法来设置XAML中的Background属性,如下所示:

    <Button.Background>
        <SolidColorBrush>
        <SolidColorBrush.Color>
            <Color A="255" R="255" G="255" B="0"/>
        </SolidColorBrush.Color>
        </SolidColorBrush>
    </Button.Background>

    对象元素的子元素

      XAML文件就像所有的XML文件一样,必须有一个单独的根对象元素。对象元素是可以支持子对象元素的。一个对象元素可以有3种类型的子元素:一个内容属性值,集合项,或一个能够通过类型转换到它的父元素的值。

    内容属性

      大多数xaml(通过定制特性)指定了一个属性,该属性可以被设置为XML元素中的任何内容。这个属性叫作内容属性,它确实是一个让XAML呈现变得更轻便简单的捷径。从某种意义上讲,这些内容属性有点像VB中的默认属性。Button中的Content属性就是这样指定的,如:

    <Button Content="OK"/>

    可以被重写为:

    <Button >
    OK
    </Button>

    还有更复杂的方式:

    <Button>
      <Button.Content>
          <Rectangle Height="40" Width="40" Fill="Black"/>
      </Button.Content>
    </Button>

    可以被重写为:

    <Button>
        <Rectangle Height="40" Width="40" Fill="Black"/>
    </Button>

    (注:这里需要注意一下,笔者测试win8应用里只有button的Content可以默认不写,其余控件都需要添加)

    集合项

      XAML允许将项添加到支持索引的两种类型的集合中:List和Dictionary。

      List是实现了System.Collection.IList接口的集合,如System.Collections.ArrayList和许多win8应用的集合类都是List。如,下面的XAML向ListBox添加了两个项,它的Items属性是实现了IList的ItemCollection类型:

      

    <ListBox > 
        <ListBox.Items>
             <ListBoxItem Content="Item 1"/>
             <ListBoxItem Content="Item 2"/> 
        </ListBox.Items> 
    </ListBox>

      System.Windows.ResourceDictionary是win8应用中的一个常用的集合类型,它实现了System.Collections.IDictionary接口,能够支持在过程式代码中添加、移除枚举键/值对。下面的XAML添加了两个Color对象到一个ResourceDictionary中。

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <Color x:Key="1" A="255" R="255" G="255" B="255"/>
        <Color x:Key="2" A="0" R="0" G="0" B="0"/>
    </ResourceDictionary>

    注意,在带有x:Key的XAML中指定的值总是被作为字符串处理的,除非使用标记扩展,但不会尝试使用类型转换。

      为了避免混淆,在转换子元素时,任何一个有效的XAML解析器或编译器必须遵循下面的规则:

    1. 如果该类型实现了IList接口,就为每个子元素调用IList.Add。
    2. 否则,如果该类型实现了IDictionary,就为每个子元素调用IDictionary.Add,在该值的键和元素中使用x:Key特性值。
    3. 否则,如果父元素支持内容属性(由System.Windows.Markup.ContentPropertyAttribute表示),而且子元素的类型与该内容属性是兼容的,就把子元素作为它的值。
    4. 否则,如果子对象是普通文本,且有类型转换器将子对象转换为父类型(没有在父元素上设置属性),则把子元素作为类型转换器的输入,将输出作为父对象的实例。
    5. 其他情况下则抛出错误。

    下一节我将带领大家学习如何将XAML与过程式代码混合使用,在运行时加载和解析XAML

  • 相关阅读:
    Linux服务器集群系统(一)--转
    linux文件操作命令--转
    HTTP Referer二三事---转
    Linux / Unix Command: bunzip2--reference
    SimpleUrlHandlerMapping 处理器映射的配置--转
    CSRF 攻击的应对之道--转
    Java 7之集合类型
    Flyweight_pattern--reference
    21 Free SEO Tools For Bloggers--reference
    存储在图的形式——邻接列表
  • 原文地址:https://www.cnblogs.com/yeanzhi/p/2932122.html
Copyright © 2020-2023  润新知