1.4-XAML语法基础:x命名空间xmlns:x
x命名空间,又叫XAML命名空间,作用于XAML的编译过程。我们知道,XAML代码,最终通过XAML编译器,编译为中间代码IL,并与后台C#代码的编译结果合并。而在编译的过程中,经常需要告诉编译器一些重要信息,比如应该与哪个C#类的编译结果合并、XAML声明的元素是public还是private、元素的变量名是什么…这些可以和XAML编译器沟通的工具,都在x命名空间中。【xmlns:x=“http://schemas.microsoft.com/winfx/2009/xaml”】,这是引入x命名空间的代码,x是命名空间的别名,也可以使用y或者z等,使用x只是约定俗成的习惯。x命名空间的工具,可以划分为四大类:属性、标记扩展、指令和数据类型。常用的如下所示:
- 属性,9个: x:Class、x:ClassModifier、x:Name、x:FiledModifier、x:Key、x:Arguments、x:FactoryMethod、x:TypeArguments、x:DataType
- 标记扩展,4个: x:Array、x:Null、x:Type、x:Static
- 指令,2个: x:Code、x:XData
- 类型,14个: x:Byte、x:Int16、x:Int32、x:Int64、x:Single、x:Double、x:Decimal、x:Boolean、x:Char、x:String、x:DateTime、x:TimeSpan、x:Object
一、属性:
1、x:Class。 将当前XAML文件的编译结果,与后台代码中的指定类合并。只能作为页面根元素的属性使用,x:Class的值所指向的后台类,必须使用partial关键字且继承自根元素的类型。
//XAML文件的根元素
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp7.MainPage"
</ContentPage>
//后台代码,部分类,继承自ContentPage
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
2、x:ClassModifier。 指定当前XAML文件的编译结果类具有怎样的访问级别。必须与对应的后台代码,具有相同的访问级别。
//指定访问级别为public,比较少使用
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp7.MainPage"
x:ClassModifier="public">
</ContentPage>
//后台代码也是public
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
3、x:Name。 XAML元素本质上是对象,在XAML文件中,通过x:Name来指定对象的变量名称。
//将Lable对象,命名为lable
//等效C#代码:var lable = new Lable{Text = "HelloWorld"};
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp7.MainPage"
<StackLayout>
<Label x:Name="lable" Text="HelloWorld"/>
<Button Text="ChangeLabelText" Clicked="Button_Clicked"/>
</StackLayout>
</ContentPage>
//后台代码,点击事件的响应中,使用“lable.Text”引用对象属性,并赋值
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
lable.Text = "HiChina";
}
}
4、x:FieldModifier。 XAML文件中,除根元素外,其它元素在C#代码层面,本质上就是字段。类似于x:ClassModifier,前者指定类的访问级别,后者指定字段的访问级别。
//默认为internal,定义为public,这样在其它项目中,也可以访问这个对象
<StackLayout>
<Label x:Name="lable" x:FieldModifier="public" Text="定义访问级别" />
</StackLayout>
5、x:Key。 资源字典是Dictionary<string,object>集合类型,每个集合的项目,都可以使用x:Key来定义键名。其它元素引用这个资源时,通过键名来引用。
//资源字典中,添加键值对字典,键名使用x:Key来定义
//{StaticResource Key=ChinaHi}可以简写为{StaticResource ChinaHi}
//因为Key为StaticResource的内容属性,所以可以省略
<ContentPage
x:Class="MauiApp7.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<ContentPage.Resources>
<x:String x:Key="ChinaHi">吃了吗</x:String>
</ContentPage.Resources>
<StackLayout>
<Label
x:Name="lable"
x:FieldModifier="public"
Text="{StaticResource Key=ChinaHi}" />
</StackLayout>
</ContentPage>
6/7、x:Arguments、x:FactoryMethod。 XAML中,每定义一个元素标签,本质上就是创建一个对象。在C#代码层面,创建对象的方式,除了属性赋值外,还有两个方法,一是构造函数初始化;二是工厂函数初始化。通过x:Arguments,可以给构造函数传递参数,而x:FactoryMethod可以调用工厂方法,并结合x:Arguments为工厂方法传递参数。
//Color类定义了多个构造函数和工厂函数,以此为例来说明x:Arguments和x:FactoryMethod的使用
//调用一个参数的构造方法来创建Color对象
<BoxView HeightRequest="100" WidthRequest="100">
<BoxView.Color>
<Color>
<x:Arguments>
<x:Single>0.8</x:Single>
</x:Arguments>
</Color>
</BoxView.Color>
</BoxView>
//调用三个参数的构造方法来创建Color对象
<BoxView HeightRequest="100" WidthRequest="100">
<BoxView.Color>
<Color>
<x:Arguments>
<x:Single>0.65</x:Single>
<x:Single>0.8</x:Single>
<x:Single>0.75</x:Single>
</x:Arguments>
</Color>
</BoxView.Color>
</BoxView>
//调用工厂函数FromHsla,创建Color对象
<BoxView HeightRequest="150" WidthRequest="150">
<BoxView.Color>
<Color x:FactoryMethod="FromHsla">
<x:Arguments>
<x:Double>0.23</x:Double>
<x:Double>0.42</x:Double>
<x:Double>0.69</x:Double>
<x:Double>0.7</x:Double>
</x:Arguments>
</Color>
</BoxView.Color>
</BoxView>
8、x:TypeArguments。 泛型类型,在实例化时,需要指明泛型参数的类型,x:TypeArguments的主要作用就是指定对象的泛型类型。
//泛型参数为简单类型
//引入List<T>的命名空间xmlns:scg="clr-namespace:System.Collections.Generic;assembly=netstandard"
<CollectionView>
<CollectionView.ItemsSource>
<scg:List x:TypeArguments="x:String">
<x:String>abc</x:String>
<x:String>efg</x:String>
<x:String>hij</x:String>
</scg:List>
</CollectionView.ItemsSource>
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding}" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
//泛型参数为复杂类型
<ContentPage
x:Class="MauiApp7.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:models="clr-namespace:MauiApp7.Models"
xmlns:scg="clr-namespace:System.Collections.Generic;assembly=netstandard">
<StackLayout>
<CollectionView>
<CollectionView.ItemsSource>
<scg:List x:TypeArguments="models:Employee">
<models:Employee Name="张三" Age="20" />
<models:Employee Name="李四" Age="30" />
<models:Employee Name="王五" Age="40" />
</scg:List>
</CollectionView.ItemsSource>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label
Text="{Binding Name}" />
<Label
Text="{Binding Age}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage>
9、x:Datatype。 XAML的绑定在运行时解析,造成两个问题:一是无法对绑定进行编译时校验,要到运行时才能发现;二是存在性能损耗。x:Datatype的作用,就是在编译时,明确绑定上下文的类型,可以明显改善以上两个问题,称之为编译时绑定。在XAML元素属性上声明x:Datatype后,绑定作用会向下延伸到子元素。所以一般情况下,x:Datatype和BindingContext定义在同一层级的元素上,但也可以在视觉树的任一层级声明。除了和BindingContext一起使用外,x:Datatype还可作用于DataTemplate,使集合绑定也变成编译时。
//BindingContext和x:Datatype都定义在ContentPage元素上
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataBindingDemos"
x:Class="MauiApp7.MainPage"
x:DataType="local:HslColorViewModel">
<ContentPage.BindingContext>
<local:HslColorViewModel Color="Sienna" />
</ContentPage.BindingContext>
<StackLayout Margin="10, 0">
<Slider Value="{Binding Hue}" />
<Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}" />
<Slider Value="{Binding Saturation}" />
<Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}" />
<Slider Value="{Binding Luminosity}" />
<Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}" />
</StackLayout>
</ContentPage>
//在DataTemplate中使用
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataBindingDemos"
x:Class="MauiApp7.MainPage"
x:DataType="local:HslColorViewModel">
<Grid>
<ListView ItemsSource="{x:Static local:NamedColor.All}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:NamedColor">
<ViewCell>
<StackLayout Orientation="Horizontal">
<BoxView Color="{Binding Color}"/>
<Label Text="{Binding FriendlyName}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</ContentPage>
二、标记扩展:详见标记扩展章节
- x:Array。将数组赋值给属性
- x:Null。将Null值赋值给属性
- x:Type。将类型值赋值给属性
- x:Static。将静态成员赋值给属性
三、指令
x:Code用于在XAML文档中写C#后台代码,x:XData用于引入XMLDataProvider提供的数据,都很少使用。这些工作,都应该在后台代码中完成,可以略过。
四、类型
定义资源和传递参数时,可以通过x命名空间进行类型申明,如<x:String x:Key="SayHi">HelloWorld</x:String>
,等效于C#代码 string SayHi = "HelloWorld"
。这些类型支持,与.NET支持的基本类型一一对应。我们也可以通过引用.NET的System命名空间,实现同样功能,如<sys:String x:Key="SayHi">HelloWorld</sys:String>
。目前x命名空间,提供了13个类型支持,可以分一下组:
- 整数: x:Byte、x:Int16、x:Int32、x:Int64
- 浮点数: x:Single(相当于float)、x:Double、x:Decimal
- 布尔: x:Boolean
- 字符: x:Char
- 字符串: x:String
- 日期时间: x:DateTime、x:TimeSpan
- 对象: x:Object
//在资源字典中申明类型变量
<ContentPage.Resources>
<x:String x:Key="eSayHi">How are you!</x:String>
<x:String x:Key="cSayHi">吃了吗!</x:String>
</ContentPage.Resources>
<Label Text="{StaticResource eSayHi}" />
//为构造函数传递参数
//下例中Color类有多个构造函数重载,根据传入参数,调用不同的构造函数
//使用x:Arguments传递参数
<BoxView HeightRequest="150">
<BoxView.Color>
<Color>
<x:Arguments>
<x:Single>0.9</x:Single>
</x:Arguments>
</Color>
</BoxView.Color>
</BoxView>
<BoxView HeightRequest="150">
<BoxView.Color>
<Color>
<x:Arguments>
<x:Single>0.25</x:Single>
<x:Single>0.5</x:Single>
<x:Single>0.75</x:Single>
</x:Arguments>
</Color>
</BoxView.Color>
</BoxView>