技术笔记:MAUI新生5.5

简介: 技术笔记:MAUI新生5.5

MAUI的Shell导航框架,也是以路由方式进行导航,并提供了两套导航方式,一是如前面章节所述的视觉层次结构,会自动建立导航路由,可以进行不同层次页面的导航切换;二是为页面手动注册路由,并执行代码导航。


一、注册路由


1、视觉层次结构页面的路由注册


在视觉层次结构中(Shell > FlyoutItem|TabBar > Tab > ShellContent),框架自动建立导航路由,可以直接进行导航切换。如果要通过代码导航到视觉层次页面,可以在定义视觉层次结构时,显示的定义路由,如:



[/span>Shell


......

[/span>FlyoutItem Route="animals"

[/span>Tab Title="Domestic" Route="domestic"

[/span>ShellContent


//代码效果参考:http://www.jhylw.com.cn/510735869.html

Title="Cats"

ContentTemplate="{DataTemplate view:Cats}"


Route="cats" />


[/span>ShellContent


Title="Dogs"


ContentTemplate="{DataTemplate view:Dogs}"


Route="dogs" />



[/span>ShellContent


Title="Monkeys"


ContentTemplate="{DataTemplate view:Monkeys}"


Route="monkeys" />


[/span>ShellContent


Title="Bears"


ContentTemplate="{DataTemplate view:Bears}"


Route="bears" />


[/span>ShellContent


Title="Elephants"


ContentTemplate="{DataTemplate view:Elephants}"


Route="elephants" />



[/span>ShellContent


Title="About"


ContentTemplate="{DataTemplate view:About}"


Route="about" />




animals


domestic


cats


dogs


monkeys


bears


elephants


about


2、非视觉层次结构页面的路由注册


MAUI中还有很多页面,没有在视觉层次结构中定义,这些页面需要进行手动注册路由,一般在AppShell后台代码的构造函数中进行。


public partial class AppShell : Shell


{


public AppShell()


{


InitializeComponent();


//注册非视觉层次页面路由,所有路由名称需保持唯一,它们是全局的


//当导航到视觉层次结构中的路由时,并不会创建导航堆栈;但导航到非视觉层次页面路由时,创建导航堆


Routing.RegisterRoute("dogdetail",typeof(DogDetail));


Routing.RegisterRoute("monkeydetail", typeof(MonkeyDetail));


//也可以将路由注册到不同的视觉层次结构上,可以实现跟踪当前路由层次,导航到不同的页面


//如下例中,都是导航到detail,但在dogs路由层次结构中时,将导航到DogDetail;反之,将导航到MonkeyDetail


Routing.RegisterRoute("dogs/detail", typeof(DogDetail));


Routing.RegisterRoute("monkeys/detail", typeof(MonkeyDetail));


}


}


二、执行导航


1、在视觉层次结构中,可以直接执行导航跳转。注:这些跳转页面,不会进入到导航堆栈中。


2、非视觉层次结构的页面,需要通过编程式导航来实现。


//下例为Monkeys页面,通过按钮点击事件进行导航


public partial class Monkeys : ContentPage


{


......


private async void Button_Clicked(object sender, EventArgs e)


{


//Shell.Current获得对当前Shell对象的引用,等效于((Shell)App.Current.MainPage)


//Shell对象包括了GoToAsync导航方法,以及CurrentItem、CurrentPage、CurrentState、BackButtonBehavior等属性


await Shell.Current.GoToAsync("dogdetail");


await ((Shell)App.Current.MainPage).GoToAsync("dogdetail");


await DisplayAlert("显示当前路由", Shell.Current.CurrentState.Location.ToString(), "OK");


}


}


3、绝对路由和相对路由


视觉层次结构的页面,可以通过绝对路径进行导航,如【Shell.Current.GoToAsync("//animals/domestic/dogs")】


非视觉层次结构的页面,可以通过相对路径进行导航,如【Shell.Current.GoToAsync("dogdetail")】


上下文导航。注册非视觉层次结构页面时,将路由注册到结构层次页面上,如Routing.RegisterRoute("monkeys/detail"...)。当在Monkeys页面中,导航到detail时,会匹配monkeys/detail。


向后导航。向后导航,【await Shell.Current.GoToAsync("..")】;向后导航与路由导航结合,【await Shell.Current.GoToAsync("../route")】;可以多次向后导航,【await Shell.Current.GoToAsync("../../route")】


关于路由导航,还有一些概念比较模糊,建议暂时按以上两种方式来导航


三、导航传参


1、传递参数。


1)方法一:查询字符串


//传递字符串:直接通过查询字符串传递参数


//传递一个字符串参数


await Shell.Current.GoToAsync("monkeydetail?name=sun");


//传递多个字符串参数


await Shell.Current.GoToAsync("monkeydetail?name=sun&sex=male");


//也可以使用内插值变量


string name = "sun"


await Shell.Current.GoToAsync($"monkeydetail?name={name}");


2)方法一:字典类型参数


//传递对象:通过GoToAsync方法的第二个参数,IDictionary字典类型对象传参


//传递一个对象


var p1 = new Person{Name="zs",Age=18};


var navigationParam = new Dictionary[span style="color: rgba(0, 0, 255, 1)">string, object

{


{ "person1", p1 }


};


await Shell.Current.GoToAsync($"persondetail", navigationParame);


//传递多个对象


var p1 = new Person{Name="zs",Age=18};


var p2 = new Person{Name="ls",Age=28};


var navigationParam = new Dictionary[span style="color: rgba(0, 0, 255, 1)">string, object

{


{ "person1", p1 }


{ "person2", p2 }


};


await Shell.Current.GoToAsync($"persondetail", navigationParame);


2、接收参数。


1)方法一:通过QueryProperty特性,接收路由参数


//QueryProperty特性


//QueryProperty特性的第一个参数为接收路由参数的属性,第一个参数为路由参数的键名


//通过查询参数传递的路由参数,会自动转为键值对形式


//注意接收路由参数的属性,必须是可观察属性(MVVM),触发PropertyChanged事件


【QueryProperty(nameof(Name), "name")】


【QueryProperty(nameof(Sex), "sex")】


public partial class MonkeyDetail : ContentPage


{


public MonkeyDetail()


{


InitializeComponent();


BindingContext = this; //将BindingContext设置为当前对象


}


//定义可观察属性Name来接收键名为name的路由参数


private string name;


public string Name


{


get { return name; }


set


{


name = value;


OnPropertyChanged();


}


}


//定义可观察属性Sex来接收键名为sex的路由参数


private string sex;


public string Sex


{


get { return sex; }


set


{


sex = value;


OnPropertyChanged();


}


}


}


//XAML文件中使用路由参数


[span style="color: rgba(0, 0, 0, 1)">ContentPage


......

[span style="color: rgba(0, 0, 0, 1)">Label


HorizontalOptions="Center"


Text="{Binding Name}"


VerticalOptions="Center" />


[span style="color: rgba(0, 0, 0, 1)">Label


HorizontalOptions="Center"


Text="{Binding Sex}"


VerticalOptions="Center" />


2)方法二:通过实现IQueryAttributable接口,接收路由参数(在ViewModel中使用)


//接收字符串路由参数


public class PersonDetailViewModel : IQueryAttributable, ObservableObject


{


【ObservableProperty】


private string name;


【ObservableProperty】


private string sex;


public void ApplyQueryAttributes(IDictionary[span style="color: rgba(0, 0, 255, 1)">string, object

{


name = HttpUtility.UrlDecode(query【"name"】.ToString());


sex = HttpUtility.UrlDecode(query【"sex"】.ToString());


}


}


//接收对象类型参数


public class PersonDetailViewModel : IQueryAttributable, INotifyPropertyChanged


{


【ObservableProperty】


private Person person;


public void ApplyQueryAttributes(IDictionary[span style="color: rgba(0, 0, 255, 1)">string, object

{


person = query【"p1"】 as Person;


}


...


}


四、路由守卫


1、全局守卫:类似于生命周期函数,Shell类提供OnNavigating(导航发生前)和OnNavigated(导航发生后)可重写方法,通过重写这两个方法,可以对导航进行控制,实现路由守卫的功能。OnNavigating和OnNavigated方法,在AppShell.xaml.cs中定义。


//OnNavigating和OnNavigated方法的常用属性和方法


public partial class AppShell : Shell


{


public AppShell()


{


InitializeComponent();


......


}


protected override void OnNavigating(ShellNavigatingEventArgs args)


{


base.OnNavigating(args);


ShellNavigationState current = args.Current;//当前页,可通过Location属性获取URL


ShellNavigationState target = args.Target; //目标页,可通过Location属性获取URL


ShellNavigationSource source = args.Source; //导航类型,枚举,包括Unknown/Push/Pop/PopToRoot/Insert/Remove/ShellItemChanged/ShellSectionChanged/ShellContentChanged


bool canCancle = args.CanCancel; //是否可以取消


bool canclled = args.Cancelled; //是否取消


args.Cancel(); //取消导航


//获取导航令牌,并完成导航


ShellNavigatingDeferral token = args.GetDeferral();


token.Complete();


}


protected override void OnNavigated(ShellNavigatedEventArgs args)


{


base.OnNavigated(args);


ShellNavigationState current = args.Current; //当前页


ShellNavigationState previous = args.Previous; //上一页


ShellNavigationSource source = args.Source; //导航类型


}


}


//案例一:取消各后导航


protected override void OnNavigating(ShellNavigatingEventArgs args)


{


base.OnNavigating(args);


if (args.Source == ShellNavigationSource.Pop)


{


args.Cancel();


}


}

相关文章
|
JSON 缓存 Android开发
iOS高质量的动画实现解决方案——Lottie
iOS高质量的动画实现解决方案——Lottie
1702 0
|
9天前
|
人工智能 JSON 运维
低成本AI编程新方案:DeepSeek V4-Pro接入Claude Code实战配置流程、评测与使用指南
在AI编程工具普及的当下,Claude Code凭借强大的代码理解、工程自动化、多技能调用能力,成为开发者日常开发、项目重构、自动化运维的必备终端工具。但长期使用官方原生模型,调用费用偏高,高频开发场景下成本压力十分明显。因此寻找一款接口兼容、推理能力相当、资费更低的替代模型,成为众多开发者的刚需。
576 0
|
7月前
|
人工智能 IDE 开发工具
Visual Studio 2026 正式版发布 - 适用于 Windows 上 .NET 和 C++ 开发人员的最全面 IDE
Visual Studio 2026 正式版发布 - 适用于 Windows 上 .NET 和 C++ 开发人员的最全面 IDE
1411 1
Visual Studio 2026 正式版发布 - 适用于 Windows 上 .NET 和 C++ 开发人员的最全面 IDE
|
12月前
|
存储 监控 关系型数据库
B-tree不是万能药:PostgreSQL索引失效的7种高频场景与破解方案
在PostgreSQL优化实践中,B-tree索引虽承担了80%以上的查询加速任务,但因多种原因可能导致索引失效,引发性能骤降。本文深入剖析7种高频失效场景,包括隐式类型转换、函数包裹列、前导通配符等,并通过实战案例揭示问题本质,提供生产验证的解决方案。同时,总结索引使用决策矩阵与关键原则,助你让索引真正发挥作用。
753 0
|
5月前
|
C#
C# 实现发送邮件功能(SMTP)
通过SMTP协议实现邮件发送,支持文本与附件,需配置邮箱SMTP信息(如QQ邮箱授权码)。示例代码展示C#中如何使用SmtpClient发送邮件,适用于QQ、163、Gmail等主流邮箱服务。
|
C# Android开发 虚拟化
C# 一分钟浅谈:MAUI 跨平台移动应用开发
.NET MAUI 是 Microsoft 推出的跨平台框架,支持 Windows、macOS、iOS 和 Android。本文从基础概念入手,探讨 MAUI 的常见问题、易错点及解决方案,并通过代码示例详细说明。涵盖平台特定代码、XAML 语法、数据绑定、性能优化和调试技巧等内容,帮助开发者更好地掌握 .NET MAUI。
1562 55
|
编解码 数据安全/隐私保护 计算机视觉
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
如何使用OpenCV进行同步和异步操作来打开海康摄像头,并提供了相关的代码示例。
1406 1
Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
1659 2
|
安全 网络安全
网络安全CTF比赛有哪些事?——《CTF那些事儿》告诉你
网络安全CTF比赛有哪些事?——《CTF那些事儿》告诉你
|
IDE 开发工具 C++
AvaloniaUI项目离线开发全攻略:IDE安装、模板应用与NuGet私有化部署一站式解决
本文详细介绍了在离线环境中开发Avalonia UI项目的完整解决方案,包括Visual Studio 2022和JetBrains Rider的离线安装、Avalonia UI模板的配置、私有NuGet服务的部署与使用,以及NuGet包的制作和上传。通过这些步骤,您可以在网络受限或完全离线的环境中顺利进行Avalonia UI项目的开发。
AvaloniaUI项目离线开发全攻略:IDE安装、模板应用与NuGet私有化部署一站式解决

热门文章

最新文章