MAUI新生1.1-XAML语法基础:语法入门
一、XAML(MAUI的XAML)和HTML
- 两者相似,都是标签语言组成的树形文档。每个标签元素,可视为一个对象,通过标签属性(Attribute),为对象的属性(Property)、事件等成员赋值。此处特别将Attribute和Proterty提出来,两者中文都叫属性,但Attribute对应于UI层面,Property对应于代码层面,一部分Attribute与Proterty一一对应,但另一部分Attribute可能对应着对象的事件、命令等。
- 区别①,HTML通过浏览器渲染为UI控件,而XAML先要通过编译器转为中间代码,并与后台C#代码合并,然后通过MAUI映射为Native对象,再由本机渲染为UI控件。
- 区别②,XAML有后台的cs文件,除了使用XAML标签,还可以通过等效C#代码来创建对象。通过C#后台代码,我们可以清楚的感受到标签的对象本质。
二、XAML的基本概念:以下案例中出现的元素/控件分别为:Button-按钮,Lable-单行或多行文本,StackLayout-水平或垂直排列布局,Grid-行列布局,ContentPage-内容页面
1、XAML的元素和属性
2、属性的赋值方式
①字符串赋值:值类型属性可以直接通过字符串赋值。部分复杂类型,也能通过内置转换器,将字符串自动转换为对象类型
②元素属性:属性为复杂的对象类型时,可以通过元素属性的方式赋值(也叫属性元素),即以元素的形式来表达属性
③扩展标记:通过扩展标记(大括号),属性的值可以引用其它源的值或对象。其中数据绑定Binding是扩展标记之一。
3、内容属性和子元素
①ContentPage属于页面类控件,其内容属性为Content,只能有一个子元素,所以一般页面类控件的子元素使用布局类控件。
②StackLayout属于布局类控件,其内容属性为Children,是一个集合类型,可以放置多个子元素。
③很多元素都有内容属性,但属性名称各异,比如上例中的Contentpage.Content和Stack.Children都是内容属性,内容属性可以省略。
4、附加属性
①上例中属性Grid.Row和Grid.Column,在Label元素上使用,但它们属于Grid。
②在等效的c#代码中,设置子元素所在行列,表现为调用Grid的两个静态方法,参数为子元素和行列
③附加属性属于可绑定属性,将在后续章节中深入学习其实现原理。
5、根元素和多页面
①MAUI是传统的多页面应用,区别于目前流行的单页面应用(如React、Vue等),页面的组织、导航、状态管理等,都更加直白简单。
②每个页面,都必须要有一个根元素,代表当前页面的类型,目前有ContentPage、FlyoutPage、NavigationPage、TabbedPage等几种页面类型。
③每个页面,在C#层面,本质是由开发者定义的类,由xaml定义的部分类和后台代码定义的部分类组成。根元素指定了这个类的父类类型,x:Class指定了这个类的名称。
④属性xmlns和xmlns:x,引用命名空间,相当于using。属性值像一个网址,但和网址没有关系,可以认为是多个命名空间的集合。每个页面可以有一个默认的xmlns,这个命名空间下的类型可以直接引用,如上例中的xmlns属性,引用了maui的所有控件类型,所以可以直接使用控件,而不需要前缀。而xmlns:x,引用了xaml命名空间,使用了别命x,使用时需要加前缀x:使用,如x:Class。
⑤上例中的两个命名空间默认引入,其中xmlns:x称之为x命名空间,这个命名空间比较特殊,与XAML编译器相关,规定了编译器在将XAML标签语言编译为C#中间语言时的一些特定行为。比如上例中的x:Class,就指示编译器在编译这个类时,编译为类名为MainPage的部分类。(MauiApp6.MainPage为类的全路径名称)。
6、事件和命令
①事件和命令,均提供了用户与UI的交互功能。
②事件为传统的事件响应机制,事件响应(回调),写在当前页面的后台代码文件中。如当前面页为MainPage.xmal,后台文件为MainPage.xaml.cs。
③命令属于MVVM模式,能够直接触发命令的控件很有限,但事件可以通过Behaviors转为命令。我们使用MVVM开发模式后,基本就很少在后台文件中写代码,后续详述。
7、命名空间
(1)引入程序集的命名空间
//引入当前程序集的命名空间 <ContentPage ... xmlns:local="clr-namespace:MyMauiApp" ...> </ContentPage> //引入指定程序集的命名空间 <ContentPage ... xmlns:local="clr-namespace:Controls;assembly=MyControlLibrary" ...> </ContentPage>
(2)使用网址形式引入多个命名空间
//定义两个控件库 namespace MyFirst.Controls { public class CircleButton : Button { ... } } namespace MySecond.Controls { public class HeavyButton : Button { ... } } //新建 AssemblyInfo.cs文件 [assembly: Preserve] [assembly: XmlnsDefinition("http://mycompany.com/controls", "MyFirst.Controls")] [assembly: XmlnsDefinition("http://mycompany.com/controls", "MySecond.Controls")] //在XAML页面中引入自定义的网址命名空间 <ContentPage ... xmlns:controls="http://mycompany.com/schemas/controls" ...> .... </ContentPage>