MAUI Shell导航:如何为导航栈各页面传递查询参数?
解决MAUI Shell导航栈多页面传参问题
一、给导航栈中每个页面单独传递参数
MAUI Shell默认的GoToAsync只会把查询参数传递给最终目标页面,要给栈中每个页面传参,可采用以下两种方案:
1. 分步导航并替换栈
通过分步执行导航操作,为每个页面单独传递参数,同时利用ShellNavigationOptions控制栈的替换逻辑:
// 清空现有栈并导航到A页面,传递id=2 await Shell.Current.GoToAsync($"//A?id=2", new ShellNavigationOptions { ClearStack = true }); // 导航到B页面,传递id=3 await Shell.Current.GoToAsync($"B?id=3"); // 导航到C页面,传递id=4 await Shell.Current.GoToAsync($"C?id=4"); // 导航到最终的Detail页面,传递id=1 await Shell.Current.GoToAsync($"Detail?id=1");
每个页面需通过[QueryProperty]特性绑定参数:
[QueryProperty(nameof(Id), "id")] public partial class APage : ContentPage { public string Id { get; set; } protected override void OnNavigatedTo(NavigatedToEventArgs args) { base.OnNavigatedTo(args); // 这里可直接使用Id参数 Console.WriteLine($"A页面获取到的id: {Id}"); } }
2. 利用Shell导航事件注入参数
通过监听Shell.Navigating事件,解析导航URL的每个分段,为即将入栈的页面手动注入参数:
// 在AppShell构造函数中注册事件 public AppShell() { InitializeComponent(); Shell.Current.Navigating += OnShellNavigating; } private void OnShellNavigating(object sender, ShellNavigatingEventArgs e) { var urlSegments = e.Target.Location.ToString().Split('/').Where(s => !string.IsNullOrEmpty(s)).ToList(); foreach (var segment in urlSegments) { // 拆分路由与参数 var parts = segment.Split('?'); var route = parts[0]; var paramDict = parts.Length > 1 ? parts[1].Split('&').ToDictionary(p => p.Split('=')[0], p => p.Split('=')[1]) : new Dictionary<string, string>(); // 获取目标页面实例并赋值参数 var pageItem = Shell.Current.CurrentItem.Items.FirstOrDefault(i => i.Route == route); if (pageItem?.CreateContent() is IQueryPage targetPage && paramDict.ContainsKey("id")) { targetPage.Id = paramDict["id"]; } } } // 定义统一参数接口 public interface IQueryPage { string Id { get; set; } } // 页面实现接口 public partial class BPage : ContentPage, IQueryPage { public string Id { get; set; } }
二、返回时给上一级页面传递参数
要实现类似..?id=20的返回传参,可选择以下两种方式:
1. 基于QueryProperty接收返回参数
返回时通过GoToAsync传递参数,上一级页面用[QueryProperty]接收:
// 在Detail页面执行返回并传参 await Shell.Current.GoToAsync($"..?id=20"); // 在C页面接收参数 [QueryProperty(nameof(ReturnedId), "id")] public partial class CPage : ContentPage { public string ReturnedId { get; set; } protected override void OnNavigatedTo(NavigatedToEventArgs args) { base.OnNavigatedTo(args); if (!string.IsNullOrEmpty(ReturnedId)) { Console.WriteLine($"C页面获取到返回的id: {ReturnedId}"); } } }
2. 直接操作上一级页面实例
通过导航栈获取上一级页面实例,直接赋值参数,适合传递复杂对象:
// 在Detail页面返回前传递数据 var previousPage = Shell.Current.Navigation.NavigationStack[^2]; if (previousPage is CPage cPage) { cPage.ReturnedId = "20"; // 也可传递自定义对象 cPage.CustomData = new CustomModel { Id = 20, Name = "Test" }; } await Shell.Current.GoToAsync("..");
内容的提问来源于stack exchange,提问作者Lukas KUCHTA
相关产品推荐
相关产品推荐

