MAUI新生1.2-XAML语法基础:标记扩展{}

标记扩展,使属性值可以引用其他源的值或对象,比如引用资源字典、引用其它控件的属性值、绑定ViewModel类属性等。标记扩展的语法有大括号{}和尖括号<>两种方式,但x:Array比较特殊,只能使用尖括号。下个章节,深入学习标记扩展后,将能够理解两者区别。为方便学习和记忆,将标记扩展归纳为以下几类:

  • 引用资源:StaticResource、DynamicResource
  • 引用元素:x:Reference,RelativeSource
  • 引用静态成员:x:Static
  • 特殊值:x:Array、x:Null、x:Type
  • 数据绑定:Binding
  • 其它:跨平台OnPlatform/OnIdiom、字体图标FontImage、主题样式AppThemeBinding、模板绑定TemplateBinding

 

 

一、引用资源:StaticResource、DynamicResource

每个继承自VisualElement的对象,都有一个Resources属性,属性值为Dictionary<string,object>类型的集合对象,这些集合对象可作为资源,提供给控件树中的子元素使用。

 

复制代码
 1 <ContentPage
 2     x:Class="MauiApp7.MainPage"
 3     xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
 4     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
 5 
 6     <ContentPage.Resources>
 7         <Color x:Key="PrimaryColor">Black</Color>
 8     </ContentPage.Resources>
 9     <StackLayout>
10         <Label Text="HelloWorld" TextColor="{StaticResource PrimaryColor}" />
11     </StackLayout>
12 
13 </ContentPage>
复制代码

 代码解读:

6-8行:在ContentPage的Resources属性上,创建一个Dictionary<string,object>集合元素,其中键为“PrimaryColor”,值为Color类型的对象。Color类型有多个重载构造函数,传入字符串颜色名称,为其中一种创建对象的方式。

10行:通过StaticResource标记扩展,使TextColor属性的值,引用key为“PrimaryColor”的字典资源。框架会从元素自身的Resources属性开始,延着控件树向上查找匹配,如果找到,则返回其值,查找终止。如果未找到,会一直延伸到应用的根元素App.xaml的Application为止。如果在Application的Resources属性中都未找到,则会返回一个XamlParseException编译异常。

补充说明: 

①定义Resources属性的代码中,隐藏了内容属性,完整代码应是:<ContentPage.Resources><ResourceDictionary>......</ResourceDictionary></ContentPage.Resources>

②StaticResource和DynamicResource的使用方法一致,两者唯一的区别在于,如果在运行时修改引用的数据源,StaticResource不会更新,而DynamicResource会实时更新

③资源字典理论上可以放任何对象资源,但一般用于创建样式、颜色、控件模板、数据模板、转换器的对象资源

 

 

 

二、引用元素/控件:x:Reference,RelativeSource

进行属性绑定时,除了MVVM模式中,绑定ViewModel的属性,有时还会绑定当前页面或指定页面的元素/控件的属性值,通过x:Reference或RelativeSource来设置绑定源。

1、x:Reference,直接通过元素名称(使用x:Name属性定义)来引用 

复制代码
 1 <ContentPage
 2     x:Class="MauiApp7.MainPage"
 3     xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
 4     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
 5     
 6     <StackLayout Padding="10">
 7 
 8         <Slider
 9             x:Name="slider"
10             Maximum="100"
11             VerticalOptions="Center" />
12 
13         <Label Text="{Binding Value, Source={x:Reference slider}}" />
14 
15         <Label
16             BindingContext="{x:Reference slider}"
17             Rotation="{Binding Value}"
18             Text="HelloWord" />
19 
20     </StackLayout>
21     
22 </ContentPage>
复制代码

 

代码解读:

9行:通过x:Name属性,给Slider对象定义一个变量名称。

13行:直接定义Binding属性绑定,将属性Text的值,与slider对象的Value属性绑定。其中Binding的属性Source,通过x:Reference扩展标记,引用slider对象。

16-17行:先定义Label元素的绑定上下文BindingContext为slider,此处的BindingContext可以认为就是绑定的Source。定义好绑定上下文后,可以直接通过Binding绑定上下文拥有的属性。

补充说明:

①包含绑定源和路径的完整写法是{Binding Path=Value, Source={x:Reference slider}},上例子Path省略了

  

2、RelativeSource,从当前元素开始,延着控件树,以相对位置的方式,查子父或子元素

复制代码
//绑定源设置为自己
<BoxView
    HeightRequest="200"
    WidthRequest="{Binding Source={RelativeSource Self}, Path=HeightRequest}"
    Color="Red" />


//绑定源设置为上级
//AncestorType定向在控制树上向上找哪种类型,AncestorLevel定义找几层
//下例结果为Red
<StackLayout Padding="10" BackgroundColor="Red">
    <StackLayout Padding="10" BackgroundColor="Yellow">
        <StackLayout Padding="10" BackgroundColor="{Binding Source={RelativeSource AncestorType={x:Type StackLayout}, AncestorLevel=2}, Path=BackgroundColor}" />
    </StackLayout>
</StackLayout>
复制代码

 

 

 

三、引用静态成员:x:Static

引用C#定义的静态成员、枚举、常量等 

复制代码
 1 //先定义一个C#静态类
 2 public static class AppConstants
 3 {
 4     public static double Title1FontSize = 40;
 5     public static double Title2FontSize = 32;
 6     public static double Title3FontSize = 28;
 7     public static double ContentFontSize = 16;
 8 }
 9 
10 //在XAML中引用静态成员
11 <ContentPage
12     x:Class="MauiApp7.MainPage"
13     xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
14     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
15     xmlns:local="clr-namespace:MauiApp7">
16     
17     <StackLayout Padding="10">
18         <Label Text="This is Title" FontSize="{x:Static local:AppConstants.Title1FontSize}"/>
19         <Label Text="This is Content" FontSize="{x:Static local:AppConstants.ContentFontSize}"/>
20     </StackLayout>
21     
22 </ContentPage>
复制代码

 

代码解读:

15行:引入命名空间MauiApp7(案例项目名称),并起别名为local

18-19行:通过x:Static引入静态成员,访问方式【命名空间别名:类.属性】

 

 

四、特殊值:x:Type、x:Array、x:Null

1、x:Type,等效于C#的typeof()

复制代码
 1 //点击按钮,执行新增Lable元素命令,命令参数为Lable类型
 2 <ContentPage
 3     x:Class="MauiApp7.MainPage"
 4     xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
 5     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 6     xmlns:local="clr-namespace:MauiApp7">
 7 
 8     <StackLayout x:Name="stackLayout" Padding="10">
 9         <Button
10             Command="{Binding CreateLableCommand}"
11             CommandParameter="{x:Type Label}"
12             Text="新增Lable元素" />
13     </StackLayout>
14 
15 </ContentPage>
16 
17 
18 //后台代码为
19 public partial class MainPage : ContentPage
20 {
21     public ICommand CreateLableCommand { get; private set; }
22     public MainPage()
23     {
24         InitializeComponent();
25         CreateLableCommand = new Command<Type>((Type viewType) => {
26             var label = (Label)Activator.CreateInstance(viewType);
27             label.Text = "这是新创建的Label";
28             stackLayout.Add(label);
29         });
30         BindingContext= this;
31     }
32 }
复制代码

代码解读:

10-11行:按钮绑定CreateLableCommand命令,命令的参数为Lable类型,相当于typeof(Lable)

30行:绑定上下文设置为当前页面,这样Binding才可以找到在后台代码中定义的CreateLableCommand命令

25-29行:创建一个命令回调,并赋值给命令属性

26行:根据传入的Type参数,创建对象,并强转为Lable类型。

28行:stackLayout的内容属性为集合类型,Add方法添加label对象。完整写法应该是stackLayout.Children.Add(label),省略了Children内容属性。

 

2、x:Array,将数组赋值给属性,结合x:Type使用,定义数组类型。

复制代码
 1 <ContentPage
 2     x:Class="MauiApp7.MainPage"
 3     xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
 4     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 5     xmlns:local="clr-namespace:MauiApp7">
 6 
 7     <ListView Margin="10">
 8         <ListView.ItemsSource>
 9             <x:Array Type="{x:Type Color}">
10                 <Color>Red</Color>
11                 <Color>Green</Color>
12                 <Color>Yellow</Color>
13             </x:Array>
14         </ListView.ItemsSource>
15         <ListView.ItemTemplate>
16             <DataTemplate>
17                 <ViewCell>
18                     <BoxView Margin="3" Color="{Binding}" />
19                 </ViewCell>
20             </DataTemplate>
21         </ListView.ItemTemplate>
22     </ListView>
23 
24 </ContentPage>
复制代码

代码解读:

8-14行:ListView的ItemsSource(数据源)属性值为Color类型的数组

15-21行:ListView的ItemsTemplate(数据项模板)属性值为DataTemplate

 

3、x:Null,将属性值设置为空null

复制代码
 1 <ContentPage
 2     x:Class="MauiApp7.MainPage"
 3     xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
 4     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 5     xmlns:local="clr-namespace:MauiApp7">
 6 
 7     <ContentPage.Resources>
 8         <Style TargetType="Label">
 9             <Setter Property="BackgroundColor" Value="Red" />
10         </Style>
11     </ContentPage.Resources>
12 
13     <StackLayout>
14         <Label Text="背景色使用Style定义的样式" />
15         <Label BackgroundColor="{x:Null}" Text="背景色不使用Style定义的样式" />
16     </StackLayout>
17 
18 </ContentPage>
复制代码

代码解读:

8-10行:在页面资源字典里,定义一个样式,目标元素为Label,设置背景色属性为红色,未指定Key,当前页面的所有Lable都会隐式应用这个Style。隐式指,不用通过StaticResource标记扩展,所有Lable都会使用这个样式。

15行:将背景色属性设置为空值,相当于不使用隐式设置的背景色样式。

 

 

五、数据绑定:Binding

Binding是XAML中最重要的核心概念,后续章节再详述,本章节只介绍最简单的使用。

复制代码
//绑定最基本的要素:源、目标和路径
//源通过BindingContext属性,将slider设置为源
//目标是Label的属性Rotation
//绑定路径为slider的Value属性值
<ContentPage
    x:Class="MauiApp7.MainPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:MauiApp7">

    <StackLayout Padding="10,0">
        <Label
            BindingContext="{x:Reference Name=slider}"
            Rotation="{Binding Path=Value}"
            Text="TEXT" />

        <Slider
            x:Name="slider"
            Maximum="360" />
    </StackLayout>

</ContentPage>


//以上代码也可以使用以下方式,直接设置Source
<StackLayout Padding="10,0">
    <Label
        Rotation="{Binding Source={x:Reference slider}, Path=Value}"
        Text="TEXT" />

    <Slider
        x:Name="slider"
        Maximum="360"/>
</StackLayout>
复制代码

 

 

 

六、其它:跨平台OnPlatform/OnIdiom、字体图标FontImage、主题样式AppThemeBinding

1、跨平台OnPlatform/OnIdiom

复制代码
//BoxView在不同平台上有不同的宽高和颜色
//下例中使用了简写,完整写法为{OnPlatform Default=Yellow...}
//平台类型包括:Default、iOS、Android、MacCatalyst、Tizen、WinUI
<BoxView Color="{OnPlatform Yellow, iOS=Red, Android=Green}"
     WidthRequest="{OnPlatform 250, iOS=200, Android=300}"  
     HeightRequest="{OnPlatform 250, iOS=200, Android=300}"/>


//BoxView在不同设备上有不同的宽高和颜色
//设置类型包括:Default、Phone、Tablet、Desktop、TV、Watch
<BoxView Color="{OnIdiom Yellow, Phone=Red, Desktop=Blue}"
     WidthRequest="{OnIdiom 100, Phone=200, Desktop=400}"
     HeightRequest="{OnIdiom 100, Phone=200, Desktop=400}"/>


//OnPlatform和OnIdiom使用尖括号来表达。繁琐很多。标记扩展简化了属性赋值
<BoxView>
    <BoxView.Color>
        <OnPlatform x:TypeArguments="Color">
            <On Platform="iOS" Value="Red"/>
            <On Platform="Android" Value="Green"/>
        </OnPlatform>
    </BoxView.Color>
</BoxView>
复制代码

 

2、主题样式AppThemeBinding

MAUI可以设置Light和Dark两个主题,可以设置属性在不同主题下的属性值,有些类似于跨平台或设备的设置

//Label文字颜色,根据不同主题显示为不同颜色
//主题设置详见后续章节
<Label Text="Light主题时为绿色,Dark主题时为红色"
           TextColor="{AppThemeBinding Light=Green, Dark=Red}" />

 

3、字体图标FontImage

复制代码
//【&#xf30c;】为字体图标unicode值,和HTML一样,在XAML里,需要使用&#方式
<Image BackgroundColor="#D1D1D1" Source="{FontImage &#xf30c;, FontFamily=Ionicons, Size=44}" />

//以上字体图标,使用尖括号表达
<Image BackgroundColor="#D1D1D1">
    <Image.Source>
        <FontImageSource Glyph="&#xf30c;"
                         FontFamily="Ionicons"
                         Size="44" />
    </Image.Source>
</Image>

//引用字体的基本步骤:
//第一步:通过将字体拖到项目的 Resources\Fonts 文件夹中,并设置ItemGroup
<ItemGroup>
   <MauiFont Include="Resources\Fonts\*" />
</ItemGroup>
//第二步:注册字体MauiProgram.cs
var builder = MauiApp.CreateBuilder();
builder
    .UseMauiApp<App>()
    .ConfigureFonts(fonts =>
    {
    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
    });
复制代码

 

4、模板绑定TemplateBinding将在控件模板章节详述

 

 

posted @   functionMC  阅读(1006)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示