Xamarin.Forms移动开发系列4 :XAML基础
摘要 本文介绍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基础的更多相关文章
- Xamarin.Forms移动开发系列5 :XAML标记扩展
摘要 本文主要讲述Xamarin.Forms中XAML的标记扩展. 前言 在Xamarin.Forms移动开发系列4 :XAML基础一文中提到过XAML标记扩展,本文将对标记扩展进行更深入的了解. 大 ...
- Xamarin.Forms移动开发系列3:项目剖析
摘要 本文主要进行Xamarin.Forms应用程序剖析. 前言 本文介绍Xamarin.Forms应用程序剖析. 由于本系列重点研究对象为Xamarin.Forms,所以对Xamarin.Andro ...
- Xamarin.Forms移动开发系列1:介绍和安装
摘要 Xamarin成立于2011年5月16日.Xamarin 是一套基于C#语言的跨平台移动应用开发工具,2016年2月24日被微软正式收购. 前言 很早就已经听说强大的.NET生态中有一个移动开发 ...
- Xamarin.Forms移动开发系列2:创建和调试
摘要 本文将介绍如何通过VS2019创建Xamarin.Forms应用程序,以及如何进行调试. 前言 本文介绍Xamarin.Froms应用程序的创建和调试. 开发环境 1.Visual Studio ...
- Xamarin.Forms教程开发的Xcode的下载安装
Xamarin.Forms教程开发的Xcode的下载安装 Xamarin.Forms教程开发的Xcode的下载安装,Xcode是开发iOS应用程序的图形化开发工具.本节将讲解Xamarin.Forms ...
- Xamarin.Forms教程开发Xamarin.Forms应用程序需要的工具
开发Xamarin.Forms应用程序需要的工具 Xamarin.Forms教程开发Xamarin.Forms应用程序需要的工具,2014年5月8日在发布的Xamrin 3中引进了Xamarin.Fo ...
- Xamarin.Forms跨平台开发入门-第二部分:深入解析
英文原文: https://developer.xamarin.com/guides/xamarin-forms/getting-started/hello-xamarin-forms/deepdiv ...
- 使用Xamarin.Forms跨平台开发入门 Hello,Xamarin.Forms 第一部分 快速入门
本文介绍了如何使用VisualStudio开发Xamarin.Forms 应用程序和使用Xamarin.Forms开发应用的基础知识,包括了构建和发布Xamarin.Forms应用的工具,概念和步骤. ...
- Xamarin.Forms 移动开发
Xamarin 提供两种原生app开发技术:1. Xamarin Native, 包括 Xamarin.Android, Xamarin.iOS, Xamarin.Mac 2. Xamarin 跨平台 ...
随机推荐
- Docker相关安装和卸载
安装: 1.Docker要求CentOS系统的内核版本高于 3.10 ,通过 uname -r 命令查看你当前的内核版本是否支持安账docker 2.更新yum包:sudo yum update 3. ...
- 探索ASP.Net Core 3.0系列六:ASP.NET Core 3.0新特性启动信息中的结构化日志
前言:在本文中,我将聊聊在ASP.NET Core 3.0中细小的变化——启动时记录消息的方式进行小的更改. 现在,ASP.NET Core不再将消息直接记录到控制台,而是正确使用了logging 基 ...
- 解决 cannot find reference 'LSHForest' in '__init__.py'
from sklearn.neighbors import LSHForest cannot find reference 'LSHForest' in '__init__.py'报错 pip3 li ...
- mongodb 导出制定的查询结果
1.mongo查询语句: db.quarkContext.find({"submitTime":{"$gt":ISODate("2019-07-13T ...
- CodeForces 463D DP
Gargari got bored to play with the bishops and now, after solving the problem about them, he is tryi ...
- Chrome教程之使用Chrome DevTools命令菜单运行命令
1.模拟移动设备 点击 Toggle Device Toolbar 2.限制网络流量和 CPU 占用率 要限制网络流量和 CPU 占用率,请从 Throttle 列表中选择 Mid-tier mobi ...
- JavaScript的闭包特性如何给循环中的对象添加事件(一)
初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...
- Winforn中设置ZedGraph多条Y轴时曲线刻度不均匀问题解决
场景 Winform中实现ZedGraph的多条Y轴(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1001322 ...
- C# Random
一.简介 在Random类用于创建随机数.(当然是伪随机的.) 二.Random用法 例: Random rnd = new Random(); int month = rnd.Next(1, 13) ...
- BCP 运行错误
记录下使用bcp导出csv文件时的错误: [Microsoft][ODBC SQL Server Driver][SQL Server]对象名 '***'无效问题的解决方案器 我们要对student数 ...