.NET MAUI中基于MVVM捕获复选框选中项并更新列表
解决方案:MAUI中不修改模型实现CollectionView复选框选中项捕获
核心思路
通过ViewModel维护一个选中状态字典跟踪每个Rayon的选中状态,避免修改原有模型;利用MVVM命令处理复选框的切换事件,按钮点击时根据字典状态筛选出选中项存入目标集合。
步骤1:完善ViewModel代码
确保已安装CommunityToolkit.Mvvm NuGet包(用于ObservableObject和RelayCommand),修改ViewModel如下:
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Newtonsoft.Json; using System.Collections.ObjectModel; using System.Net.Http; public partial class CreateSupplierPageViewModel : ObservableObject { // 选中的Sections集合,自动通知UI更新 private ObservableCollection<Rayon> _selectedSections = new(); public ObservableCollection<Rayon> SelectedSections { get => _selectedSections; set => SetProperty(ref _selectedSections, value); } // 所有Sections集合 public ObservableCollection<Rayon> Sections { get; set; } = new ObservableCollection<Rayon>(); // 跟踪每个Rayon的选中状态,键为Rayon.Id private Dictionary<int, bool> _selectionStates = new Dictionary<int, bool>(); public async Task GetSectionsList() { var sectionUrl = "https://localhost:7282/api/Sections/GetSections"; using (var client = new HttpClient()) { var apiResponse = await client.GetAsync(sectionUrl); if (apiResponse.IsSuccessStatusCode) { var content = await apiResponse.Content.ReadAsStringAsync(); var sectionList = JsonConvert.DeserializeObject<List<Rayon>>(content); if (sectionList != null) { // 直接替换集合,比逐个添加高效 Sections = new ObservableCollection<Rayon>(sectionList); // 初始化选中状态字典,默认未选中 foreach (var section in sectionList) { _selectionStates[section.Id] = false; } } } } } public static async Task<CreateSupplierPageViewModel> Create() { var vm = new CreateSupplierPageViewModel(); await vm.Initialize(); return vm; } private async Task Initialize() { await GetSectionsList(); } public CreateSupplierPageViewModel() { } // 处理复选框选中/取消事件 [RelayCommand] private void OnSectionToggled(Rayon rayon) { if (_selectionStates.ContainsKey(rayon.Id)) { _selectionStates[rayon.Id] = !_selectionStates[rayon.Id]; } } // 处理按钮点击,收集选中的Sections [RelayCommand] private void GetSelectedSections() { SelectedSections.Clear(); foreach (var rayon in Sections) { if (_selectionStates.TryGetValue(rayon.Id, out bool isSelected) && isSelected) { SelectedSections.Add(rayon); } } // 此处可添加对SelectedSections的后续逻辑,如提交、打印等 } }
步骤2:修改XAML代码
首先在XAML根元素添加ViewModel命名空间(替换为你的项目实际命名空间):
xmlns:vm="clr-namespace:YourApp.ViewModels"
然后修改CollectionView和Button的绑定:
<CollectionView ItemsSource="{Binding Sections}" Grid.Row="1"> <CollectionView.ItemTemplate> <DataTemplate> <HorizontalStackLayout> <CheckBox Color="#0B4C90" Command="{Binding Source={RelativeSource AncestorType={x:Type vm:CreateSupplierPageViewModel}}, Path=OnSectionToggledCommand}" CommandParameter="{Binding .}" /> <Label Text="{Binding SectionName}" FontSize="20" FontAttributes="Bold" TextColor="#0B4C90"/> </HorizontalStackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> <Button Text="Get Sections" Command="{Binding GetSelectedSectionsCommand}" />
关键说明
- 选中状态跟踪:用
Dictionary<int, bool>记录每个Rayon的选中状态,键为Rayon.Id,避免修改原有模型结构。 - 命令绑定:复选框通过
RelativeSource向上查找ViewModel上下文,将当前Rayon对象作为参数传递给OnSectionToggledCommand,实现状态切换。 - 按钮逻辑:点击按钮时遍历所有
Rayon,根据字典状态筛选出选中项,存入SelectedSections集合。
内容的提问来源于stack exchange,提问作者Yassine El mesbahy
相关产品推荐
相关产品推荐

