视频讲解
第3章〓宝剑锋从磨砺出〓梅花香自苦寒来——MAUI开发理论
3.1XAML可扩展的应用程序标记语言
3.1.1XAML概述
XAML(eXtensible Application Markup Language)是基于XML的可扩展应用程序标记语言。XAML具有跨语言、跨平台、层次化、可读性的特点,是一种声明式的、具有层次结构的标记性语言,主要用于界面设计。XAML组件包括*.xaml 界面文件和
*.xaml.cs代码文件。这样做的好处是将界面设计和业务逻辑相分离,实现界面与逻辑的解耦,提升可维护性、可理解性、可测试性。XAML能够方便地实现数据绑定机制,实现MVVM设计模式。Visual Studio能够支持XAML热重载,实时修改界面代码后,调试过程无须重启,能够在UI上形成快速迭代,提升工作效率。Visual Studio还能够支持XAML可视化,提供XAML可视化树,使用属性视图能够方便地对属性进行编辑操作。目前,.NET MAUI应用程序中没有针对XAML的视觉设计器。
XAML由以下元素组成。
声明。XAML文件根节点属性。包括XAML命名空间引用声明、XAML动态库引用声明、XAML类引用声明、XAML标记声明。
对象。基于XAML描述,可创建、可实例化。包括容器、控件、资源。
资源。与对象关联的存储或定义,具有统一定义数据、样式或行为的功效。包括数据资源、样式资源、模板资源。
属性。定义控件的数据、外观或行为。包括普通属性、内容属性、附加属性。
模板。定义控件的整体效果,具有复用性。
触发器。能够根据事件或属性变化更改控件外观。
动画。提供渐变性、交互性、动态性效果。
标记扩展。自定义组件、控件,扩充标记。
3.1.2XAML基本语法
XAML是标准的XML,但是还包括自身的一些特性,如普通属性、内容属性、附加属性和标记扩展。
Visual Studio新建.NET MAUI XAML文件的方法是,在项目中选择文件夹后,右击,从弹出的快捷菜单中选择“菜单项添加”→“类”命令,然后选择.NET MAUI ContentPage(XAML)模板,如图31所示,并输入文件名。这样在选中的文件夹下面自动生成XAML文件和XAML文件相对应的类文件。XAML文件相对应的类文件默认是隐藏的,需要在Visual Studio中展开才能看到。
图31新建.NET MAUI ContentPage(XAML)
【例31】XAML基本语法。
NewPage1.xaml代码如下:
1
2
6
7
11
12
首行和普通XML一样,声明了XML文件的版本号和编码方式。ContentPage是内容页面,对应的属性含义详见3.1.4节内容。内容部分定义了VerticalStackLayout(垂直布局)。内部包括Label(标签)控件,具有Text(文本)属性,属性值显示Welcome to.NET MAUI!,VerticalOptions 垂直对齐方式属性是Center(居中)显示和HorizontalOptions水平对齐方式属性也是Center显示。属性统一使用键值对的方式进行定义,中间使用赋值运算符,属性值使用双引号进行包裹。XAML中的标签可以采用单标签或双标签的形式。
NewPage1.xaml.cs代码如下:
1namespace MAUIDemo.Pages;
2
3public partial class NewPage1 : ContentPage
4{
5public NewPage1()
6{
7InitializeComponent();
8}
9}
NewPage1.xaml.cs是NewPage1.xaml 对应的代码文件。NewPage1类继承ContentPage类,属于分部类。构造方法调用InitializeComponent()完成界面控件初始化操作。命名空间与XAML文件中 x:Class相对应。
3.1.3XAML标记扩展
XAML标记扩展的目的是提升扩展性和灵活性。下面直接引入示例展示XAML标记扩展的各种使用方式。
【例32】XAML标记扩展。
1
2
8
13
18
22
26
30
36
41
42
46
47
48x:Array AAA
49x:Array BBB
50x:Array CCC
51
52
53
54
58
66
67
68
69
70
71
上述示例从上往下依次对应标记扩展的使用方式。
属性设置。类似HTML/XML属性语法,对控件设置相应的属性。
静态扩展。使用x:StaticExtension标记扩展并配置Member属性设置相应的属性。
静态引用。使用x:Static标记扩展并配置Member属性设置相应的属性。
插值静态扩展。使用x:StaticExtension标记扩展结合花括号插值语法并配置Member属性设置相应的属性。
插值静态引用。使用x:Static标记扩展结合花括号插值语法并配置Member属性设置相应的属性。
插值静态引用。使用x:Static标记扩展结合花括号插值语法并省略Member属性直接设置相应的属性。
命名空间引用。通过命名空间机制引入变量作为属性值。
控件引用。BindingContext(绑定上下文)属性中使用x:Reference标记扩展引用之前通过x:Name定义的控件,Binding(绑定)属性配置绑定的变量。
类型标记扩展。使用x:Type标记扩展,后面指定类型参数。
数组标记扩展。使用x:Array标记扩展,通过Type属性指定数组元素类型。
空值标记扩展。使用x:Null标记扩展,表示空。
平台标记扩展。使用OnPlatform标记扩展,分别设置iOS、Android、Tizen、MacCatalyst 不同平台显示的参数值。
习语标记扩展。使用OnIdiom标记扩展,分别设置Phone 手机、Desktop 桌面、Tablet 平板不同终端显示的参数值。
主题标记扩展。使用AppThemeBinding标记扩展,结合 StaticResource引用相应的资源展示不同的主题。
自定义标记扩展。继承IMarkupExtension接口自定义标记扩展。
RGBExtension.cs代码如下:
1namespace MAUIDemo.Core
2{
3public class RGBExtension : IMarkupExtension
4{
5public int R
6{
7get;
8set;
9}
10public int G
11{
12get;
13set;
14}
15public int B
16{
17get;
18set;
19}
20public Color ProvideValue(IServiceProvider serviceProvider)
21{
22return Color.FromRgb(R,G,B);
23}
24object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
25{
26return (this as IMarkupExtension).ProvideValue(serviceProvider);
27}
28}
29}
上述代码展示了自定义标记扩展的使用,RGBExtension 继承IMarkupExtension,泛型参数是Color(颜色)类。重写ProvideValue()方法完成对象转换。
XAML标记扩展涉及的语法现象示例程序的运行结果如图32所示。
图32XAML标记扩展涉及的语法现象示例程序的运行结果
3.1.4XAML命名空间
命名空间是用于组织类文件的层次化结构。例33包含了常见的命名空间引用情况。
【例33】XAMLPage.xaml 命名空间。
1
ContentPage根节点包含了6个属性。
x:Class。声明当前组织XAML命名空间的类。
xmlns。XML Namespaces 声明了.NET MAUI命名空间。
xmlns:x。声明了.NET MAUI关于 xaml的命名空间。
xmlns:core。引入自定义的命名空间。clrnamespace指定命名空间前缀。
xmlns:sys。引入系统定义的命名空间。clrnamespace指定命名空间前缀,assembly属性指定命名空间对应的程序集。
Title。声明当前页面标题。
3.1.5XAML参数传递
XAML参数传递主要通过x:Arguments标记扩展。
【例34】XAML参数传递。
1
12
XAML参数传递构造对象有如下方式。
参数构造。使用x:Arguments标记扩展,传入参数构造相应对象。
工厂构造。使用x:Arguments标记扩展,结合 x:FactoryMethod标记扩展利用工厂方法传入参数构造相应对象。
3.1.6XAML动态加载
【例35】XAML动态加载。
XAML动态加载界面代码如下:
1
5
6
XAML动态加载逻辑代码如下:
1public ICommand OnClick
2{
3get;
4set;
5}
6public ICommand OnRuntimeClick
7{
8get;
9set;
10}
11public ICommand OnFindClick
12{
13get;
14set;
15}
16OnClick = new Command((Type type) =>
17{
18View view = (View)Activator.CreateInstance(type);
19view.HorizontalOptions = LayoutOptions.Center;
20view.VerticalOptions = LayoutOptions.Center;
21vStackLayout.Insert(9, view);
22});
23OnRuntimeClick = new Command(() =>
24{
25string xaml = "