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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:52:19