Xamarin/C#中如何更新SelectMultipleBasePage的WrappedItems数据?
解决SelectMultipleBasePage中WrappedItems数据更新的问题
嘿,我来帮你搞定这个List无法刷新的问题!首先得说清楚:你现在用的List<WrappedSelection<T>>是普通集合,它不会自动通知UI数据变化,而且ListView绑定普通List后,直接增删元素也不会触发界面更新。下面是具体的解决步骤:
1. 把WrappedItems换成ObservableCollection
ObservableCollection是专门为Xamarin这类UI框架设计的集合,它会在元素增删时自动触发UI更新。修改你的SelectMultipleBasePage定义:
public class SelectMultipleBasePage<T> : ContentPage { // 替换成ObservableCollection,自动通知UI变化 public ObservableCollection<WrappedSelection<T>> WrappedItems { get; set; } = new ObservableCollection<WrappedSelection<T>>(); // 完善WrappedSelection,确保IsSelected属性触发通知 public class WrappedSelection<T> : INotifyPropertyChanged { private bool _isSelected; public T Item { get; set; } public bool IsSelected { get => _isSelected; set { if (_isSelected != value) { _isSelected = value; OnPropertyChanged(nameof(IsSelected)); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } // 你的WrappedItemSelectionTemplate代码保持不变 public class WrappedItemSelectionTemplate : ViewCell { public WrappedItemSelectionTemplate() : base() { Label Title = new Label(); // ...你的其他布局代码 // View = grid; } } }
2. 构造函数中正确初始化ObservableCollection
在创建SelectMultipleBasePage实例时,直接把转换后的WrappedSelection对象传入ObservableCollection:
public SelectMultipleBasePage(List<T> items) { // 用ObservableCollection构造函数直接初始化排序后的包装数据 WrappedItems = new ObservableCollection<WrappedSelection<T>>( items.OrderBy(x => x.Title).Select(item => new WrappedSelection<T>() { Item = item, IsSelected = false }) ); ListView mainList = new ListView() { ItemsSource = WrappedItems, ItemTemplate = new DataTemplate(typeof(WrappedItemSelectionTemplate)), IsPullToRefreshEnabled = true, }; // ...其他页面布局代码 }
3. 添加/清空数据的正确方式
现在你可以直接对WrappedItems进行操作,UI会自动同步更新:
添加新数据(比如下拉刷新场景)
mainList.Refreshing += async (sender, e) => { // 获取最新的用户数据 var updatedItems = await App.Database.User.GetItemsAsync(); // 遍历新数据,避免重复添加(根据User的唯一标识判断,比如Id) foreach (var item in updatedItems.OrderBy(x => x.Title)) { if (!WrappedItems.Any(w => (w.Item as Models.Users).Id == item.Id)) { WrappedItems.Add(new WrappedSelection<T> { Item = item, IsSelected = false }); } } // 结束下拉刷新状态 mainList.EndRefresh(); };
清空所有数据
// 直接调用Clear方法,UI会自动清空列表内容 WrappedItems.Clear();
额外优化:批量添加数据
如果需要一次性添加大量数据,可以给ObservableCollection写个扩展方法实现批量添加:
public static class ObservableCollectionExtensions { public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> items) { foreach (var item in items) { collection.Add(item); } } }
之后就能用WrappedItems.AddRange(newWrappedItems)来批量添加数据,减少UI更新次数。
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

