You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:50:30