.NET MAUI:如何通过MVVM与CollectionView实现单/多选功能
MAUI CollectionView MVVM 多选实现修正方案
针对你在MAUI中结合CollectionView与MVVM实现多选功能时遇到的问题,以下是具体修正步骤与完整代码:
核心问题修正点
- 修正
SelectedPersons类型:将ObservableCollection<Object>改为ObservableCollection<Person>,保证与数据源元素类型匹配,避免类型不兼容问题 - 移除冗余属性:多选模式下无需单独的
SelectedPerson属性,避免逻辑混淆 - 优化命令逻辑:直接通过绑定的选中集合处理业务,无需手动维护选中项(MAUI会自动同步)
修正后的ViewModel代码
namespace Sandbox.ViewModel; [QueryProperty("Persons","Persons")] public partial class SelectPageViewModel : ObservableObject { [ObservableProperty] private ObservableCollection<Person> persons; [ObservableProperty] private ObservableCollection<Person> selectedPersons; public SelectPageViewModel() { Persons = new(); SelectedPersons = new(); } [RelayCommand] private async Task SelectionChanged() { if (SelectedPersons.Count == 0) return; string selectedNames = string.Join(", ", SelectedPersons.Select(p => p.Name)); bool keepSelection = await App.Current.MainPage.DisplayAlert("已选中项", $"选中人员:{selectedNames}\n是否保留当前选择?", "是", "否"); if (keepSelection) { Dictionary<string, object> param = new() { { "SelectedPersons", SelectedPersons } }; await Shell.Current.GoToAsync("..", param); } else { // 清空所有选中项 SelectedPersons.Clear(); } } }
修正后的View代码
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:viewmodel="clr-namespace:Sandbox.ViewModel" xmlns:model="clr-namespace:Sandbox.Model" x:DataType="viewmodel:SelectPageViewModel" x:Class="Sandbox.View.SelectPage" Title="SelectPage"> <Grid RowDefinitions="Auto,*" Padding="10"> <Label Grid.Row="0" Text="选择列表项" FontSize="Large" FontAttributes="Bold" /> <CollectionView Grid.Row="1" ItemsSource="{Binding Persons}" SelectionMode="Multiple" SelectedItems="{Binding SelectedPersons, Mode=TwoWay}" SelectionChangedCommand="{Binding SelectionChangedCommand}"> <CollectionView.ItemTemplate> <DataTemplate x:DataType="model:Person"> <!-- 添加选中状态的视觉反馈,提升用户体验 --> <Grid Padding="10" BackgroundColor="{Binding Source={RelativeSource AncestorType={x:Type CollectionViewItem}}, Path=IsSelected, Converter={StaticResource BoolToColorConverter}}"> <Label Text="{Binding Name}" FontSize="Medium" /> </Grid> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </Grid> </ContentPage>
可选:添加选中状态转换器(增强UI体验)
若需要直观区分选中项,可添加布尔值转颜色的转换器:
转换器代码
namespace Sandbox.Converters; public class BoolToColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return (bool)value ? Colors.LightSkyBlue : Colors.Transparent; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
在View中注册转换器
在ContentPage的资源节点添加注册:
<ContentPage.Resources> <converters:BoolToColorConverter x:Key="BoolToColorConverter" /> </ContentPage.Resources>
关键说明
- 类型匹配:
SelectedItems绑定的集合类型必须与ItemsSource的元素类型完全一致,否则MAUI无法自动同步选中状态 - 双向绑定:
SelectedItems必须设置Mode=TwoWay,确保ViewModel能实时获取最新的选中集合 - 自动同步:多选模式下,MAUI会自动将用户选中/取消选中的项同步到绑定的
SelectedPersons集合中,无需手动添加或移除 - UI反馈:添加选中状态的视觉提示是多选功能的必要体验优化,避免用户无法感知选中状态
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

