摘要 本文介绍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. Docker相关安装和卸载

    安装: 1.Docker要求CentOS系统的内核版本高于 3.10 ,通过 uname -r 命令查看你当前的内核版本是否支持安账docker 2.更新yum包:sudo yum update 3. ...

  2. 探索ASP.Net Core 3.0系列六:ASP.NET Core 3.0新特性启动信息中的结构化日志

    前言:在本文中,我将聊聊在ASP.NET Core 3.0中细小的变化——启动时记录消息的方式进行小的更改. 现在,ASP.NET Core不再将消息直接记录到控制台,而是正确使用了logging 基 ...

  3. 解决 cannot find reference 'LSHForest' in '__init__.py'

    from sklearn.neighbors import LSHForest cannot find reference 'LSHForest' in '__init__.py'报错 pip3 li ...

  4. mongodb 导出制定的查询结果

    1.mongo查询语句: db.quarkContext.find({"submitTime":{"$gt":ISODate("2019-07-13T ...

  5. CodeForces 463D DP

    Gargari got bored to play with the bishops and now, after solving the problem about them, he is tryi ...

  6. Chrome教程之使用Chrome DevTools命令菜单运行命令

    1.模拟移动设备 点击 Toggle Device Toolbar 2.限制网络流量和 CPU 占用率 要限制网络流量和 CPU 占用率,请从 Throttle 列表中选择 Mid-tier mobi ...

  7. JavaScript的闭包特性如何给循环中的对象添加事件(一)

    初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...

  8. Winforn中设置ZedGraph多条Y轴时曲线刻度不均匀问题解决

    场景 Winform中实现ZedGraph的多条Y轴(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1001322 ...

  9. C# Random

    一.简介 在Random类用于创建随机数.(当然是伪随机的.) 二.Random用法 例: Random rnd = new Random(); int month = rnd.Next(1, 13) ...

  10. BCP 运行错误

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