摘要 本文介绍Xamarin.Forms创建用户界面的语言:XAML基础部分。

前言

本文介绍Xamarin.Forms定义用户界面的语言:XAML。

本篇篇幅较长,主要讲述XAML语法,以及对其他基础知识的粗略认识,后续会分篇探索XAML中的几个重点知识。

大纲

1.XAML概述

2.初始XAML

3.基础语法(重点讲述)

4.标记扩展

5.数据绑定

内容

1.XAML概述

XAML是一种基于XML语言,由微软创建的实例化对象的代码,并组织这些对象的父子级关系,主要应用在WPF、Silverlight、Xamarin.Forms等。

开发人员可以在XAML文件中使用Xamarin.Forms提供的视图、布局和页面来创建用户界面。

XAML文件可以编译,也可以嵌入到可执行文件中。无论哪种方法,XAML代码信息都会在构建时解析,并在运行时再次解析以实例化和初始化对象,以及在这些对象和编程代码之间建立连接。

XAML优势:

● 相比C#代码更简洁易读

● XAML中的父子级关系能够轻松模拟用户界面对象的父子层次结构。

● 能够借助可视化设计工具进行工具化和生成。(Xamarin.Forms暂时没有可视化工具,必须手动编写)

XAML缺点:

● 不能包含事件代码。

● 不能包含多重循环(各别控件除外)。

●  不能包含条件处理。

2.初识XAML

在Xamarin.Forms应用程序中,XAML主要用于定义页面的可视内容,并与Code-Behind文件一起工作。

下面是MainPage.xaml的内容:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1"
x:Class="App1.MainPage"> <StackLayout>
<!-- Place new controls here -->
<Label Text="Welcome to Xamarin Forms!"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout> </ContentPage>

首先,声明了三个命名空间(xmlns)

第一个命名空间指向是Xamarin的网站,这意味着在xmln文件中不带任何前缀的标签使用的是Xamarin.Forms中的类,如<ContentPage>、<StackLayout>。

第二个命名空间指向是Microsoft的网站,声明了x的前缀,这意味着带x的标签使用的是xaml本身固有的元素和属性,如:x:Class="App1.MainPage"的属性,使得该xaml文件在App1命名空间下定义了一个MainPage类。

第三个命名空间指向的当前的.NET Standard库App1,这意味着带local前缀的标签使用的是.NET Standard库App1中的类。

往下的代码就是放置一些控件并设置属性。

上述代码创建了一个StackLayout的布局控件,在这个控件内又创建了一个Label文本控件,设置属性Text(文本内容)为“Welcome to Xamarin Forms”,并且设置为水平和垂直居中。

下面是MainPage.xaml.cs的内容:


using Xamarin.Forms; namespace App1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
}

MainPage是一个partial类,这意味着还有另一个分部类的定义,而MainPage构造函数中调用的InitializeComponent方法正是该分部类的一个方法,该方法又调用LoadFromXaml方法从.NET Standard库中加载的XAML文件,初始化xaml文件中的定义的所有对象,将C#代码中的事件处理程序附加到xmal文件中设置的事件,然后设置成页面内容。

可以简单理解为InitializeComponent方法就是初始化xaml界面的。

注:上述分部类是在Visual Studio生成项目是自动生成的,在项目的obj/debug目录下可以找到一个名为MainPage.xaml.g.cs的文件,该文件就是MainPage的分部类。

3.基础语法

3.1 元素和属性

XAML通过XML元素和属性来实例化对象,如:

<StackLayout>
<Label Text="Welcome to Xamarin.Forms!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
TextColor="Red"/>
</StackLayout>

Label是Xamarin.Forms对象,在XAML代码中使用XML元素来表示。

HorizontalOptions、VerticalOptions、TextColor是Xamarin.Forms属性,在XAML代码中使用XML元素的属性来表示。

3.2 属性元素

在XAML中某些属性不能简单的用字符串来表示(比如后文提到的内容属性),这时候就需要用到属性元素,如:

<StackLayout>
<Label Text="Welcome to Xamarin.Forms!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<!--属性元素-->
<Label.TextColor>Red</Label.TextColor>
</Label>
</StackLayout>

这时候TextColor虽然是Xamarin.Forms属性,但在XAML代码中使用XML元素来表示。

将属性TextColor以XML标签的形式单独设置为一个元素,称为属性元素(Property Elements)。

属性元素标签中不能出现任何其他内容,属性值的内容定义在属性元素开始和结束标记之间。

属性元素是XAML特有的语法,对于XML解码器,Label.Textcolor只是一个普通的子元素,并没有特殊意义。

3.3 附加属性

附加属性是一种特殊类型的属性,在一个类中定义,然后附加到其他对象,在XAML中以类.属性名的方式使用,如:


<StackLayout>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- 位于1行1列 -->
<Label Text="Top Left" Grid.Row="0" Grid.Column="0" />
<!-- 位于1行2列 -->
<Label Text="Top Right" Grid.Row="0" Grid.Column="1" />
<!-- 位于2行1列 -->
<Label Text="Bottom Left" Grid.Row="1" Grid.Column="0" />
<!-- 位于2行2列 -->
<Label Text="Bottom Right" Grid.Row="1" Grid.Column="1" />
</Grid>
</StackLayout>

Grid元素拥有RowDefinitions和ColumnDefinitions属性,他们声明了Grid的行和列以形成网格,但Grid并没有单元格的概念,所以不能将Grid中的元素直接写在单元格中,而是通过另一种方式。

可以看到Grid中的子元素Label中都包含一个Grid.Row和Grid.Column属性,这两个属性是定义在Grid对象中的,但是附加到Label对象,称为附加属性(Attached Properties)。

Grid.Row和Grid.Column分别指定了对应的Label位于Grid的几行几列,以达到将Label放置到对应单元格的效果。

关于附加属性,后续可能会详讲它的定义和使用,此处只讲语法。

3.4 内容属性

先看一段基础XAML代码:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1"
x:Class="App1.MainPage">
<StackLayout>
<Label Text="Welcome to Xamarin.Forms!"/>
</StackLayout>
</ContentPage>

在XAML中一个元素标签之间只能放该元素的属性值,并不支持直接将一个对象写在元素标签里。

而上述代码看起来就是直接将StackLayout对象写在ContentPage元素下,这是怎么回事呢?

在Xamarin.Forms中定义的作为XAML元素的类,可以加一个ContentProperty特性,该特性可以标记一个属性为内容属性。在ContentPage元素标签按F12,就可以看到该特性:

该特性将ContentPage的Content属性标记为内容属性。在XAML文件中,为Content属性赋值时就不需要写属性元素标签,在ContentPage开始标签和结束标签之间的内容都假定被赋值给Content属性。

StackLayout,Grid,AbsoluteLayout,RelativeLayout等布局元素都派生自Layout<View>,查看Layout<T>元数据也可以看到内容属性:

此外Label元素也同样包含内容属性:

因此常常可以看到Label的另一种写法:直接将Text属性放在Label标签之间。

<Label>Welcome to Xamarin.Forms!</Label>

看完以上叙述,你可能还并不太理解什么叫内容属性,下面看看没有使用内容属性语法的代码:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1"
x:Class="App1.MainPage">
<ContentPage.Content>
<StackLayout>
<StackLayout.Children>
<Label>
<Label.Text>Welcome to Xamarin.Forms!</Label.Text>
</Label>
</StackLayout.Children>
</StackLayout>
</ContentPage.Content>
</ContentPage>

这是最开始那段代码用完整的属性元素写法写出来的,两段代码是等效的,可以做对比,就能轻松明白什么叫内容属性(Content Properties)。

友情提示:看懂内容属性需要先掌握属性元素。

4.标记扩展

XAML标记扩展是XAML中的一个重要功能,它可以将属性值设置为从其他源间接引用的对象或值,对于使用共享对象和整个应用程序中的常量以及数据绑定特别重要。

标记扩展在XAML文件中表现为“{属性设置}”。

通常情况下,属性可以设置为显示的值,如字符串,数字,枚举等,但有时候需要引用其他地方定义的值,或者进行代码处理,这时候就会用到XAML标记扩展,如:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1"
x:Class="App1.MainPage">
<ContentPage.Resources>
<x:String x:Key="introduce">
Xamarin is a cross-platform mobile development tool
</x:String>
</ContentPage.Resources>
<StackLayout>
<!-- 使用标记扩展来使用ContentPage.Resoures里定义的值 -->
<Label Text="{StaticResource introduce}"/>
<Button Text="{StaticResource introduce}"/>
</StackLayout>
</ContentPage>

上述代码中,{StaticResource introduce}就是使用了标记扩展StaticResource来使用其他地方定义的属性值。因为StaticResource实现了IMarkupExtension接口,所以被称为标记扩展。

常用的标记扩展还有x:Static、x:Reference、x:Type、x:Array、x:Null、OnPlatform、OnIdiom等,此外你还可以自定义标记扩展。

关于标记扩展后续会深入了解。

5.数据绑定

XAML中提供了快捷和便利的数据绑定方式:{Binding}标记扩展。

在C#中进行数据绑定,通常会先设置目标的BindingContext为源目标对象,再调用目标对象的SetBinding方法。

但在XAML中,你可以通过{x:Static}、{StaticResource}、{x:Reference}等标记扩展来指定目标对象的BindingContext,然后使用{Binding}标记扩展来进行数据绑定。如:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1"
x:Class="App1.MainPage"> <StackLayout>
<Label x:Name="lblSource" Text="我是源对象" /> <Label x:Name="lbl" Text="{Binding Text}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
BindingContext="{x:Reference Name=lblSource}"/>
</StackLayout> </ContentPage>

第二个Label使用{x:Reference}标记扩展,指定了第一个Label对象为数据源对象,然后第二个Label就可以使用{Binding}标记扩展,来使用数据源对象的属性,作为自己的属性。

上述代码将导致两个Label的文本内容都是“我是源对象”。

关于数据绑定后续会深入了解。

欢迎添加个人微信号:Like若所思。

欢迎关注我的公众号,不仅为你推荐最新的博文,还有更多惊喜和资源在等着你!一起学习共同进步!

Xamarin.Forms移动开发系列4 :XAML基础的更多相关文章

  1. Xamarin.Forms移动开发系列5 :XAML标记扩展

    摘要 本文主要讲述Xamarin.Forms中XAML的标记扩展. 前言 在Xamarin.Forms移动开发系列4 :XAML基础一文中提到过XAML标记扩展,本文将对标记扩展进行更深入的了解. 大 ...

  2. Xamarin.Forms移动开发系列3:项目剖析

    摘要 本文主要进行Xamarin.Forms应用程序剖析. 前言 本文介绍Xamarin.Forms应用程序剖析. 由于本系列重点研究对象为Xamarin.Forms,所以对Xamarin.Andro ...

  3. Xamarin.Forms移动开发系列1:介绍和安装

    摘要 Xamarin成立于2011年5月16日.Xamarin 是一套基于C#语言的跨平台移动应用开发工具,2016年2月24日被微软正式收购. 前言 很早就已经听说强大的.NET生态中有一个移动开发 ...

  4. Xamarin.Forms移动开发系列2:创建和调试

    摘要 本文将介绍如何通过VS2019创建Xamarin.Forms应用程序,以及如何进行调试. 前言 本文介绍Xamarin.Froms应用程序的创建和调试. 开发环境 1.Visual Studio ...

  5. Xamarin.Forms教程开发的Xcode的下载安装

    Xamarin.Forms教程开发的Xcode的下载安装 Xamarin.Forms教程开发的Xcode的下载安装,Xcode是开发iOS应用程序的图形化开发工具.本节将讲解Xamarin.Forms ...

  6. Xamarin.Forms教程开发Xamarin.Forms应用程序需要的工具

    开发Xamarin.Forms应用程序需要的工具 Xamarin.Forms教程开发Xamarin.Forms应用程序需要的工具,2014年5月8日在发布的Xamrin 3中引进了Xamarin.Fo ...

  7. Xamarin.Forms跨平台开发入门-第二部分:深入解析

    英文原文: https://developer.xamarin.com/guides/xamarin-forms/getting-started/hello-xamarin-forms/deepdiv ...

  8. 使用Xamarin.Forms跨平台开发入门 Hello,Xamarin.Forms 第一部分 快速入门

    本文介绍了如何使用VisualStudio开发Xamarin.Forms 应用程序和使用Xamarin.Forms开发应用的基础知识,包括了构建和发布Xamarin.Forms应用的工具,概念和步骤. ...

  9. Xamarin.Forms 移动开发

    Xamarin 提供两种原生app开发技术:1. Xamarin Native, 包括 Xamarin.Android, Xamarin.iOS, Xamarin.Mac 2. Xamarin 跨平台 ...

随机推荐

  1. [算法模版]Tarjan爷爷的几种图论算法

    [算法模版]Tarjan爷爷的几种图论算法 前言 Tarjan爷爷发明了很多图论算法,这些图论算法有很多相似之处(其中一个就是我都不会).这里会对这三种算法进行简单介绍. 定义 强连通(strongl ...

  2. SpringMVC+ajax文件上传实例教程

    原文地址:https://blog.csdn.net/weixin_41092717/article/details/81080152 文件上传文件上传是项目开发中最常见的功能.为了能上传文件,必须将 ...

  3. git 给分支添加描述 管理分支实用方法

    1.背景 在我们工作中,正常情况我们处在一个迭代中,一个人最多会有几个功能,比较正常的操作我们会给每个大功能创建不同的分支,方便管理. 我们可以非常愉快的进行版本管理,遇到特殊情况我们也可以方便版本退 ...

  4. redis之布隆过滤器

    布隆过滤器是什么? 布隆过滤器可以理解为一个不怎么精确的 set 结构,当你使用它的 contains 方法判断某个对象是否存在时,它可能会误判.但是布隆过滤器也不是特别不精确,只要参数设置的合理,它 ...

  5. 使用Charles进行HTTPS抓包及常见问题

    在渗透过程中,需要对每一个参数,每一个接口,每一个业务逻辑构建测试用例,为此,抓包分析是必不可少的一个过程.在PC端,Burpsuite成为了渗透必备的神器,然而,使用Burpsuite有时候抓取不到 ...

  6. 使用NumPy、Numba的简单使用(二)

    本来要写NLP第三课动态规划的,日了,写到一半发现自己也不会了,理论很简单,动态规划咋回事也知道,但是实现在源码上还是有点难度,现在简单给予题目描述,小伙伴也可以来思考一下,例题一,我们现在有1元硬币 ...

  7. JSP是Servlet详解

    前言:前一段时间写了好多Servlet和JSP相关的博客,自以为理解的差不多了,岂不知人外有人,天外有天,代码外还有源码,受高人点拨,看了一下Servlet源码,感触颇深,再也不敢说懂了,不明白生活的 ...

  8. yield return,yield break

    转自, http://www.cnblogs.com/kingcat/archive/2012/07/11/2585943.html yield return 表示在迭代中下一个迭代时返回的数据,除此 ...

  9. BCP 运行错误

    记录下使用bcp导出csv文件时的错误: [Microsoft][ODBC SQL Server Driver][SQL Server]对象名 '***'无效问题的解决方案器 我们要对student数 ...

  10. 基于Spring Cloud Netflix的TCC柔性事务和EDA事件驱动示例

    Solar Spring Cloud为开发者提供了快速构建分布式系统中的一些常见工具,如分布式配置中心,服务发现与注册中心,智能路由,服务熔断及降级,消息总线,分布式追踪的解决方案等. 本次实战以模拟 ...