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

如何在Maui Shell导航返回时获取CollectionView选中项

在Shell导航中获取返回的选中项内容

以下是几种实用的实现方式,适配MAUI/Xamarin.Forms的Shell导航场景:

方法一:通过导航Query参数传递

这种方式直接利用Shell导航的参数机制,将选中项序列化后作为返回参数传递。

1. 选择页面(SelectAnItem)处理选中事件

在CollectionView的选中事件中,将选中项序列化后通过导航返回:

private async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var selectedItem = e.CurrentSelection.FirstOrDefault() as YourItemModel;
    if (selectedItem == null) return;

    // 序列化复杂类型为JSON字符串(简单类型可直接传值)
    var itemJson = System.Text.Json.JsonSerializer.Serialize(selectedItem);
    // 返回上一页并携带参数,转义特殊字符避免解析错误
    await Shell.Current.GoToAsync($"..?selectedItem={Uri.EscapeDataString(itemJson)}");
}

2. 发起导航页面接收参数

导航返回后,从Shell的当前状态Query中提取并反序列化参数:

await Shell.Current.GoToAsync("//SelectAnItem");

// 获取返回的选中项
if (Shell.Current.CurrentState.Query.TryGetValue("selectedItem", out var itemJson))
{
    var decodedJson = Uri.UnescapeDataString(itemJson);
    var selectedItem = System.Text.Json.JsonSerializer.Deserialize<YourItemModel>(decodedJson);
    // 这里处理选中项逻辑
}

或者使用QueryProperty特性自动绑定参数,代码更简洁:

[QueryProperty(nameof(SelectedItem), "selectedItem")]
public partial class MainPage : ContentPage
{
    private YourItemModel _selectedItem;
    public YourItemModel SelectedItem
    {
        get => _selectedItem;
        set
        {
            if (value == null) return;
            // 反序列化参数
            _selectedItem = System.Text.Json.JsonSerializer.Deserialize<YourItemModel>(Uri.UnescapeDataString(value.ToString()));
            // 处理选中项逻辑
        }
    }

    private async void NavigateToSelectPage()
    {
        await Shell.Current.GoToAsync("//SelectAnItem");
    }
}

方法二:使用WeakReferenceMessenger消息传递

适合组件解耦的场景,通过消息机制传递选中项,无需依赖导航参数。

1. 定义消息类

public class SelectedItemMessage : CommunityToolkit.Mvvm.Messaging.ValueChangedMessage<YourItemModel>
{
    public SelectedItemMessage(YourItemModel value) : base(value)
    {
    }
}

2. 发起页面订阅消息

在页面生命周期方法中注册/取消注册消息,避免内存泄漏:

protected override void OnAppearing()
{
    base.OnAppearing();
    // 订阅选中项消息
    CommunityToolkit.Mvvm.Messaging.WeakReferenceMessenger.Default.Register<SelectedItemMessage>(this, (recipient, message) =>
    {
        var selectedItem = message.Value;
        // 处理选中项逻辑
    });
}

protected override void OnDisappearing()
{
    // 取消订阅
    CommunityToolkit.Mvvm.Messaging.WeakReferenceMessenger.Default.Unregister<SelectedItemMessage>(this);
    base.OnDisappearing();
}

3. 选择页面发送消息

选中项后发送消息并返回上一页:

private async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var selectedItem = e.CurrentSelection.FirstOrDefault() as YourItemModel;
    if (selectedItem == null) return;

    // 发送选中项消息
    CommunityToolkit.Mvvm.Messaging.WeakReferenceMessenger.Default.Send(new SelectedItemMessage(selectedItem));
    await Shell.Current.GoToAsync("..");
}

方法三:共享ViewModel

如果两个页面共用同一个ViewModel实例,可直接通过ViewModel的属性传递数据。

1. 定义共享ViewModel

public class SharedViewModel : CommunityToolkit.Mvvm.ComponentModel.ObservableObject
{
    private YourItemModel _selectedItem;
    public YourItemModel SelectedItem
    {
        get => _selectedItem;
        set => SetProperty(ref _selectedItem, value);
    }
}

2. 注册单例ViewModel

在MAUI的Program.cs中注册单例服务:

builder.Services.AddSingleton<SharedViewModel>();

3. 页面中使用ViewModel

发起页面:

private readonly SharedViewModel _sharedViewModel;

public MainPage(SharedViewModel sharedViewModel)
{
    InitializeComponent();
    _sharedViewModel = sharedViewModel;
}

private async void NavigateToSelectPage()
{
    await Shell.Current.GoToAsync("//SelectAnItem");
    // 导航返回后直接获取选中项
    var selectedItem = _sharedViewModel.SelectedItem;
    // 处理选中项逻辑
}

选择页面:

private readonly SharedViewModel _sharedViewModel;

public SelectAnItemPage(SharedViewModel sharedViewModel)
{
    InitializeComponent();
    _sharedViewModel = sharedViewModel;
}

private async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var selectedItem = e.CurrentSelection.FirstOrDefault() as YourItemModel;
    if (selectedItem == null) return;

    _sharedViewModel.SelectedItem = selectedItem;
    await Shell.Current.GoToAsync("..");
}

内容的提问来源于stack exchange,提问作者rm5432

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 18:35:25