如何在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
相关产品推荐
相关产品推荐

