广告: 为了方便我们大家一起学习和讨论,我开设了一个群300143953。专门关于windows phone开发学习的群。因为群刚建,所以没人。欢迎大家。另外如果出现啥错误性的问题,希望大家能够指出。毕竟我也是刚刚接触。
在windows Phone开发中,他使用的是silverlight框架,他的应用界面都是由xaml构成,他就相当于Android中的xml文件。在微软的设计理念中,Code-Behind(UI与业务逻辑的分离)经典模式在这里的体现就是xaml与xaml.cs的文件的组合。那么在使用xaml开发的时候,我们首先得知道这玩意儿是啥,这玩意儿怎么用,这玩意儿有啥注意的地方。
3.1什么是xaml
Xaml是一种声明性标记语言,他类似于HTML和xml的结合体。这也是silverlight独有的语法结构。Xaml大体上呢也遵循xml语法规则,例如标签的成对出现,每一个元素都包含有一个名称或者多个属性。在xaml中,每个属性都和silverlight类库中定义的属性对应,每个元素都和silverlight中的类的名称所对应。比如说<.Button/>元素就对应System.Windows.Controls,Button.
因为xaml是一种纯粹的标记语言,这就意味着某个元素要处理一个事件时,需要触发该元素的特定属性来处理。他就类似于asp.net采用的代码后置,将显示的UI和业务逻辑相分离。
在开发xaml中,最好使用name属性来区分和定位一个元素,这样我们在业务逻辑中就可以通过这个属性名来访问该元素。
3.2声明一个xaml元素的四大原则
1.xaml是严格区分大小写的,元素和属性的名称必须严格遵守;
2.所有属性值,无论什么数据类型,都应该包含在双引号当中;
3.所有的元素必须是封闭的,也就是说一个元素必须有开始有结束。例如<Button .../>要么自我结束,要么成对出现<Button ...></Button>
4.最终的xaml必须是合格的xml文档。
3.3 xaml的作用
1.xaml是用于声明silverlight UI以及UI中元素的主要格式,通常项目中至少有一个xaml文件表示应用程序中用于最初显示的UI界面。其他xaml文件可能是声明资源或者是其他地方用到的UI界面。
2.Xaml是用于声明支持UI界面显示不同特效的样式和模板的格式,这些样式和模板用于silverlight 控件和UI的逻辑基础。
3.Xaml的出现可以使用在不同的UI设计器上,可以使用不同的设计器结合使用,达到最完美的效果
4.Xaml的出现简化了开发的流程,使做业务逻辑的兄弟和做UI设计的朋友基本上是互不干涉。
5.Xaml的出现可以保留更多的设计原型,方便这个可视化设计中出现的版本控制。
Xaml的常规作用是用于声明对象,这些对象的属性和对象----属性的关系。声明的对象由类类型的库提供支持,相关的库可以是以下任意一个:
1.silverlight核心库;
2.分布式库,他们是在包中再发布的SDK的一部分,或者也有可能是应用程序库的缓存选项;
3.第三方控件的自定义库;
4.用户自己创建的类库;
5.其他库。通过应用程序模型进行引用的库。
3.4xaml的语法
3.4.1 xaml的命名空间
命名空间:他的作用是确定如何解释引用编程实体的字符串标记,如果重复使用字符串标记,命名空间还可以解决多义性。他的存在使得编程框架能够区分用户声明的标记和框架声明的框架声明的标记,并通过命名空间来消除可能出现的标记冲突。其实简单理解就是两点,第一点,声明引用。第二点区分标记所属的空间。
在这里xaml使用标记中提供的xml样式命名空间声明(xmlns),并将命名空间格式表示的类型属性信息和程序集信息都都与特定的xaml命名空间关联。这也使得创建应用程序时,如果要读取xaml文件,就可以区分出标记以及标记的所属。
xaml文件始终在其根元素中声明一个默认的命名空间,如果有属于该默认空间的控件元素,就不必再进行前缀限定。
Xaml命名空间用于声明他们的特定元素,也就是在该UI上显示的那些控件,
一个默认的xaml命名空间声明提供了3项信息:
1.一个前缀,该前缀代表了所属的空间。如果限定到某一个元素上,证明该元素属于那片空间
2.在xaml命名空间中定义元素的后备类型的程序集,xaml处理器必须访问此程序集才能基于xaml声明创建对象,简单理解就是说xaml处理器如果要声明创建元素,就必须先访问其所属的那片空间。
3.该程序集中的一个CLR命名空间。CLR是公共语言运行时,Common Language Runtime)和Java虚拟机一样也是一个运行时环境,它负责资源管理(内存分配和垃圾收集),并保证应用和底层操作系统之间必要的分离。
在几乎每个xaml文件中声明一个特定的命名空间是针对元素的命名空间。太蛋疼了,这手里都各式各样的资料,每一份都不一样。总结的都好郁闷了。
常见的命名空间的构造“x:前缀”:
x:Key 为ResourceDictionary中的每个资源设置唯一ID
x:Class 为xaml提供代码隐藏的类的clr命名空间和类名称。并命名由标记便宜在应用程序模型中创建的类。
x:Name 处理xaml中定义的对象元素,为该元素指定唯一名称。
3.4.2 声明对象
一个xaml文件始终只有一个元素作为其根,该元素声明的一个对象将作为某些编程结构的概念跟。或者是应用程序的整个运行时定义的对象图。根据xaml语法,可以通过3钟方法在xaml中声明变量:
1.直接使用对象元素语法:使用开始结束标记将对象实例化为xml格式的元素,可以使用该语法声明根对象或者创建用于设置属性值得嵌套对象。
2.间接性使用属性语法:使用内联关键字符串声明对象。
3.I用标记扩展
并不意味着始终可以选择使用任何语法以给定的 XAML 词汇创建对象。 词汇中的某些对象只能使用对象元素语法创建。 少量对象只能通过初始设置为属性值来创建。 事实上,在 Silverlight 中,可以使用对象元素或属性语法创建的对象比较少。 即使这两种语法格式都是可能的,也只有其中一种语法格式占主流或是最适合方案使用的格式。
除了以等同于实例化对象的方式声明对象之外,XAML 中还提供了一些可用来引用现有对象的方法。 这些对象可能在 XAML 的其他区域中定义,或者通过平台及其应用程序或编程模型的某种行为隐式存在。
3.4.2.1 使用对象元素语法声明对象
若要使用对象元素语法声明对象,需要使用以下模式编写标记,其中,objectName 是要实例化的类型的名称。 在本文档中,经常出现术语“对象元素用法”,这是用于用对象元素语法创建对象的特定标记的简称。
<objectName>
</objectName>
下面的示例是用于声明 Canvas 对象的对象元素用法。
<Canvas>
</Canvas>
许多 Silverlight 对象(例如 Canvas)可以包含其他对象。
<Canvas>
<Rectangle>
</Rectangle>
</Canvas>
为方便起见(且作为 XAML 与 XML 的一般关系的一部分),如果对象不包含其他对象,则可以使用一个自结束标记(而不是开始/结束标记对)来声明对象元素,如下面示例中的 <Rectangle /> 标记所示。
<Canvas>
<Rectangle />
</Canvas>
3.4.2.2 使用属性语法声明对象
在某些情况下,属性 (Property) 值并不只是语言基元(如字符串),此时可以使用属性 (Attribute) 语法来实例化设置该属性 (Property) 的对象,并初始化用于定义新对象的键属性 (Property)。 由于此行为绑定到属性 (Property) 设置,请参见以下各节了解有关如何使用属性 (Attribute) 语法在一个语法步骤中声明对象并设置其属性 (Property) 的信息。
初始化文本
有时可以声明对象以及所包含的用于为构造提供初始值的内部文本。 在 XAML 中,这种方法和语法称为初始化文本。 从概念上来说,初始化文本类似于调用具有参数的构造函数,但内部的 XAML 分析器实现通常不按原意来完成。
初始化文本在 Silverlight 中很有用,用来设置某些结构的初始值。 如果在资源字典中创建结构示例,则可以使用此方法,因为您打算将该结构值共享给多个目标属性。 在某些结构中,您无法使用属性语法来设置结构的值。
3.4.3 设置属性
可以设置使用对象元素语法声明的对象的属性。 可以通过多种方法使用 XAML 设置属性:
使用属性语法。
使用属性元素语法。
使用内容元素语法。
使用集合语法(通常是隐式集合语法)。
对于对象声明,用于在 XAML 中设置对象属性的此方法列表并不表示可以使用这些方法中的任何一种来设置给定的属性。 某些属性只支持其中一种方法。 某些属性 (Property) 可能支持组合;例如,支持内容元素语法的属性 (Property) 可能还通过属性 (Property) 元素语法或备选属性 (Attribute) 语法支持更详细的格式。 这取决于属性和属性使用的对象类型。 可用 XAML 设置的每个属性的参考页的"XAML 用法"部分指出了使用 XAML 语法的可能性。 Silverlight 中的对象还有一些无论使用任何方式都无法使用 XAML 设置的属性,只能使用代码来设置这些属性。
无论使用任何方式(包括 XAML 或代码)都无法设置只读属性,除非有其他机制适用。该机制可能是调用一个设置为属性的内部表示形式的构造函数重载、一个并非是严格意义上的属性访问器的帮助器方法或一个计算属性。 计算属性依赖于其他可设置属性的值,以及服务或行为对该属性值的可能影响;而这些功能在依赖项属性系统中提供。
XAML 中的集合语法给出了一种您正在设置只读属性的假象,但实际上并非如此。
3.4.3.1 使用属性 (Attribute) 语法设置属性 (Property)
使用以下语法,其中 objectName 是要实例化的对象,propertyName 是要对该对象设置的属性的名称,propertyValue 是要设置的值。
<objectName propertyName="propertyValue" .../>
-or-
<objectName propertyName="propertyValue">
...<!--element children -->
</objectName>
使用任何一种语法都可以声明对象并设置该对象的属性。 虽然第一个示例是标记中的单一元素,实际上这里有一些与 XAML 处理器如何分析此标记有关的分离步骤。 首先,对象元素的存在表明必须实例化新的 objectName 对象。 只有存在这样的实例后,才可以对它设置实例属性 propertyName。
下面的示例使用四个属性 (Attribute) 的属性 (Attribute) 语法来设置 Rectangle 对象的 Name、Width、Height 和 Fill 属性 (Property)。
<Rectangle Name="rectangle1" Width="100" Height="100" Fill="Blue" />
等效的代码可能类似以下伪代码:
Rectangle rectangle1 = new Rectangle();
rectangle1.Width=100.0;
rectangle1.Height=100.0;
rectangle1.Fill = new SolidColorBrush(Colors.Blue);
第一行是对默认构造函数的调用。请注意,Name 的值用作要向其分配构造函数结果的实例名称。
与 Name 不同,上述伪代码的第二行到第四行的分配顺序是不确定的。按照 XAML 的规则,一旦创建了此实例,XAML 分析器就必须能够按任意顺序设置这些属性。
3.4.3.2 使用属性元素语法设置属性
许多 Silverlight 属性可以使用属性元素语法来设置。若要使用属性元素语法,必须能够指定对象元素的新实例才能"填充"属性元素值。
若要使用属性元素语法,需要为要设置的属性创建 XML 元素。这些元素的形式为 <object.property>。 在标准的 XML 中,此元素只被视为在名称中有一个点的元素。 但是使用 XAML 时,元素名称中的点将该元素标识为属性元素,且 property 是 object 的属性。
在下面的语法中,property 是要设置的属性的名称,propertyValueAsObjectElement 是声明新对象的新对象元素,其值类型是该属性期望的值。
<object>
<对象.属性>
propertyValueAsObjectElement
</对象.属性>
</object>
下面的示例使用属性元素语法通过 SolidColorBrush 对象元素来设置 Rectangle 的填充。 (在 SolidColorBrush 中,Color 使用属性语法来设置。)此 XAML 的呈现结果等同于前面使用属性语法设置 Fill 的 XAML 示例。
<Rectangle
Name="rectangle1"
Width="100"
Height="100"
>
<Rectangle.Fill>
<SolidColorBrush Color="Blue"/>
</Rectangle.Fill>
</Rectangle>
3.4.3.3 使用 XAML 内容语法设置属性
一些 Silverlight 类型定义了一个启用 XAML 内容元素语法的属性。 在 XAML 内容元素语法中,您可以忽略该属性的属性元素,并可以通过提供所属类型的对象元素标记中的内容来设置该属性。 该内容通常为一个或多个对象元素。这称为 XAML 内容语法。如果 XAML 内容语法可用,则 Silverlight 参考文档中针对该属性的“XAML 用法”部分将显示该语法。
例如,Border 的 Child 属性页显示了 XAML 内容语法(而非属性元素语法),以设置 Border 的单一对象 Child 值。 下面的示例与这一用法类似:
<Border>
<Button .../>
</Border>
如果声明为 XAML 内容属性的属性也支持“松散”对象模型(在此模型中,属性类型为 Object,或具体而言为类型 String),则可以使用 XAML 内容语法将纯字符串作为内容放入开始对象标记与结束对象标记之间。例如,TextBlock 的 Text 属性 (Property) 页显示了另一种 XAML 语法,该语法使用 XAML 内容语法(而不是属性 (Attribute) 语法)来为 Text 设置一个字符串值。下面的示例与该用法类似,并设置 TextBlock 的 Text 属性,而不显式指定 Text 属性。将使用 XML 认为是内容或“内部文本”的内容来设置 Text,而不是使用属性 (attribute) 或声明对象元素。
<TextBlock>Hello!</TextBlock>
3.4.3.4 使用集合语法设置属性
在 XAML 中,有几个集合语法的变体。这一眼看上去似乎允许“设置”只读集合属性。 而实际上,XAML 允许的操作是为一个存在的集合中添加项。实现 XAML 支持的 XAML 语言和 XAML 处理器依赖于后备集合类型中的约定来启用此语法。
通常,XAML 语法中不存在保留集合项的集合类型的属性(例如,索引器或 Items 属性)。 对于集合而言,XAML 中的集合实际所需的未必是属性,而是方法:Add 方法。 调用 Add 方法就是上述约定。 当 XAML 处理器遇到 XAML 集合语法中的一个或多个对象元素时,首先通过使用其对象标记创建每个此类对象,然后通过调用集合的 Add 方法以声明顺序将每个新对象添加到包含集合中。
下面的示例演示了一个使用可构造集合类型的集合属性(可以定义实际的集合并将其实例化为 XAML 中的一个对象元素)。
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<!-- Here the GradientStopCollection tag is specified. -->
<GradientStopCollection>
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
不过,对于采用集合的 Silverlight 属性而言,XAML 分析器可根据集合所属的属性隐式知道集合的后备类型。因此,您可以省略集合本身的对象元素,如下面的示例所示。
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<!-- no explicit new GradientStopCollection, parser knows how to find or create -->
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
另外,有一些属性不但是集合属性,还标识为类的 XAML 内容属性。前面示例中以及许多其他 Silverlight 属性中使用的 GradientStops 属性就是这种情况。在这些语法中,也可以省略属性元素。这生成以下标记:
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</LinearGradientBrush>
在广泛用于控件合成的类(如面板、视图或项控件)中,此集合和内容语法的组合是最常见的。例如,下面的示例演示将两个 UI 元素合成到一个 StackPanel 中的显式 XAML 以及可能的最简单 XAML。
<!--explicit tags, and UIElementCollection commented-->
<StackPanel>
<StackPanel.Children>
<!--UIElementCollection-->
<TextBlock>Hello</TextBlock>
<TextBlock>World</TextBlock>
<!--/UIElementCollection-->
</StackPanel.Children>
</StackPanel>
<!--simple-->
<StackPanel>
<TextBlock>Hello</TextBlock>
<TextBlock>World</TextBlock>
</StackPanel>
请注意显式语法中注释掉的 UIElementCollection。将其注释掉是因为即使在对象树中将存在相关集合,也无法在 XAML 中显式指定它。这是因为 UIElementCollection 不是可构造的类。您在运行时对象树中获取的值是所属类中的一个默认初始化值,在初始化之后无法更改此值。在某些情况下,标记中会特意且显式包含集合类(例如,赋予集合一个 x:Name,以便可以在代码中更方便地引用该集合)。但是,注意不要显式声明由于其后备类型的特征而无法由 XAML 分析器构造的集合类。因为它们正在填充只读集合属性。
3.4.3.5 何时使用属性 (Attribute) 语法或属性 (Property) 元素语法来设置属性 (property)
所有支持使用 XAML 设置的属性 (Property) 都支持用于直接值设置的属性 (Attribute) 语法或属性 (Property) 元素语法,但可能不会互换支持每种语法。 某些属性支持上述两种语法,某些属性还支持其他语法选项(例如前面所示的 Text 的内容元素语法)。 属性支持的 XAML 语法的类型在某种程度上取决于该属性用作其属性类型的对象的类型。 如果该属性 (Property) 类型为基元类型(例如双精度、整型或字符串),则该属性 (Property) 始终支持属性 (Attribute) 语法。
下面的示例使用属性语法设置 Rectangle 的宽度。 Width 属性 (Property) 支持属性 (Attribute) 语法,这是因为属性 (Property) 值是双精度值。
<Rectangle Width="100" />
如果可以通过对字符串进行类型转换来创建用于设置某属性 (Property) 的对象类型,也可以使用属性 (Attribute) 语法来设置该属性 (Property)。对于基元,始终是这种情况。但是,某些其他对象类型也可以使用指定为属性值的字符串(而不是需要对象元素语法)来创建。此方法使用该特定属性或该属性类型通常所支持的基本类型转换。属性 (Attribute) 的字符串值经过分析后,字符串信息用于设置对新对象的初始化非常重要的属性 (Property)。特定类型转换器还可能创建公共属性类型的不同子类,这取决于它处理字符串中的信息的独特方式。支持此行为的对象类型将使用特殊语法(在本文档的语法部分中列出)。
下面的示例使用属性语法设置 Rectangle 的填充。当使用 SolidColorBrush 设置 Fill 属性 (property) 时,该属性 (Property) 支持属性 (Attribute) 语法。这是因为支持 Fill 属性 (Property) 的 Brush 抽象类型支持类型转换语法,该语法可以创建一个通过将属性 (Attribute) 指定的字符串作为其 Color 来初始化的 SolidColorBrush
<Rectangle Width="100" Height="100" Fill="Blue" />
如果用于设置某属性的对象支持对象元素语法,则可以使用属性元素语法来设置该属性。如果该对象支持对象元素语法,该属性也支持属性元素语法。下面的示例使用属性元素语法设置 Rectangle 的填充。当使用 SolidColorBrush 设置 Fill 属性时,该属性支持属性元素语法,这是因为 SolidColorBrush 支持对象元素语法并满足该属性的使用 Brush 类型设置其值的要求。(SolidColorBrush 也使用属性 (Attribute) 语法设置了其 Color 属性 (Property)。此 XAML 的呈现结果等同于前面使用属性语法设置 Fill 的 XAML 示例。)
<Rectangle Width="100" Height="100">
<Rectangle.Fill>
<SolidColorBrush Color="Blue"/>
</Rectangle.Fill>
</Rectangle>
由于 Brush 类型转换器的原因,SolidColorBrush 成为唯一可针对新 Fill 值选择属性 (Property) 元素语法或属性 (Attribute) 语法(不使用标记扩展用法,如资源引用或绑定)的 Brush 案例。对于可用于设置 Fill 的其他 Brush 类型,没有可用来创建该 Brush 类型的类型转换器行为。因此,如果要使用 brush 类型(例如 ImageBrush)来设置 Fill,必须对 Fill 使用属性元素语法并将 ImageBrush 声明为对象元素以提供属性值
<Rectangle Width="100" Height="100">
<Rectangle.Fill>
<ImageBrush ImageSource="forest.jpg"/>
</Rectangle.Fill>
</Rectangle>
3.5 标记扩展
标记扩展是一个在 Silverlight XAML 实现中广泛使用的 XAML 语言概念。 在 XAML 属性语法中,花括号({ 和 }})表示标记扩展用法。 此用法指示 XAML 处理不要像通常那样将属性值视为文本字符串或者视为可直接转换为文本字符串的值。 相反,分析器通常应调用支持该特定标记扩展的代码,该标记扩展可帮助从标记中构造对象树。
Silverlight 支持在其默认的 Silverlight XAML 命名空间下定义且其 XAML 分析器可以理解的以下标记扩展。
绑定:支持数据绑定,此绑定将延迟属性值,直至在数据上下文中解释此值。
StaticResource:支持引用在 ResourceDictionary 中定义的资源值。
TemplateBinding:支持 XAML 中可与模板化对象的代码属性交互的控件模板。
RelativeSource:启用特定形式的模板绑定。
Silverlight 还支持在 XAML 语言 XAML 命名空间中定义的一个非常简单的标记扩展,即 x:Null。
采用引用类型值(类型没有转换器)的属性需要属性元素语法(该语法始终创建新实例)或通过标记扩展的对象引用。 Silverlight 标记扩展通常从应用程序的对象图的其它部分返回一个现有的实例,或延时一个值到运行时。 通过使用标记扩展,每个可使用 XAML 设置的属性 (Property) 都可能可在属性 (Attribute) 语法中设置。 即使属性 (Property) 不支持对直接对象实例化使用属性 (Attribute) 语法,也可以使用属性 (Attribute) 语法为属性 (Property) 提供引用值;或者可以使特定行为能够符合用值类型或实时创建的引用类型填充 XAML 属性 (Property) 这一常规要求。
例如,下面的 XAML 使用属性 (Attribute) 语法设置 Border 的 Style 属性 (Property) 的值。 Style 属性 (Property) 采用了 Style 类的实例,这是默认情况下无法使用属性 (Attribute) 语法字符串创建的引用类型。 但在本例中,属性 (Attribute) 引用了特定的标记扩展 StaticResource。 当处理该标记扩展时,它返回对以前在资源字典中定义为键控资源的某个样式的引用。
<Canvas.Resources>
<Style TargetType="Border" x:Key="PageBackground">
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="BorderThickness" Value="5"/>
</Style>
</Canvas.Resources>
...
<Border Style="{StaticResource PageBackground}">
...
</Border>
在许多情况下,可以使用标记扩展来提供一个作为对现有对象的引用的值,或者标记扩展可以提供一个可以以属性 (Attribute) 格式设置属性 (Property) 的对象。
3.6 事件
XAML 是用于对象及其属性的声明性语言,但它也可以包含用于将事件处理程序附加到标记中的对象的语法。 接着,可以通过特定的技术(如 Silverlight)扩展 XAML 事件语法约定,这会通过编程模型集成 XAML 声明的事件。 可以将相关事件的名称指定为处理该事件的对象的属性名称。 对于属性值,可以指定在代码中定义的事件处理程序函数的名称。 XAML 处理器使用此名称在加载的对象树中创建一个委托表示形式,并将指定的处理程序添加到内部处理程序列表中。
大多数基于 Silverlight 的应用程序都是由标记和代码隐藏源生成的。 在一个项目中,XAML 被编写为 .xaml 文件,而使用 CLR 语言(如 Visual Basic 或 C#)编写代码隐藏文件。 当 XAML 文件是标记 - 编译作为 Silverlight 项目创建操作的一部分时,通过将一个命名空间和类指定为 XAML 页的根元素的 x:Class 属性来确定每个 XAML 页的 XAML 代码隐藏文件的位置。