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

.NET MAUI中如何隐藏ObservableCollection标记删除的元素?

解决ObservableCollection过滤已删除项的问题

针对你用MVVM + Microsoft.Toolkit开发,需要隐藏deleted=true项的需求,给你几个实用方案:

方案1:利用ICollectionView做过滤(适合WPF/MAUI等UI框架)

大部分UI框架的CollectionView控件可直接绑定ICollectionView,通过设置过滤规则实现隐藏已删除项,无需修改原集合:

// ViewModel中实现
private ObservableCollection<YourModel> _sourceCollection;
public ICollectionView FilteredCollection { get; }

public YourViewModel()
{
    _sourceCollection = new ObservableCollection<YourModel>();
    FilteredCollection = CollectionViewSource.GetDefaultView(_sourceCollection);
    // 设置过滤规则:只保留未标记删除的项
    FilteredCollection.Filter = item => 
    {
        if (item is YourModel model)
            return !model.deleted;
        return false;
    };
}

将FilteredCollection绑定到UI的CollectionView控件即可。当源集合新增/删除项,或某条数据的deleted属性变化时,若模型实现了INotifyPropertyChanged,可监听属性变化自动调用FilteredCollection.Refresh()触发过滤更新。

方案2:使用Microsoft.Toolkit.Collections的FilteredObservableCollection

Microsoft.Toolkit.Collections库提供了FilteredObservableCollection<T>,它是ObservableCollection的子类,支持动态过滤,会自动监听源集合变化和项的属性变化:

先安装Microsoft.Toolkit.Collections NuGet包,再在ViewModel中使用:

using Microsoft.Toolkit.Collections;

private ObservableCollection<YourModel> _sourceCollection;
public FilteredObservableCollection<YourModel> FilteredCollection { get; }

public YourViewModel()
{
    _sourceCollection = new ObservableCollection<YourModel>();
    // 初始化过滤集合,传入源集合和过滤条件
    FilteredCollection = new FilteredObservableCollection<YourModel>(_sourceCollection, 
        model => !model.deleted);
}

此方案无需手动调用刷新,当源集合变化或模型deleted属性变更时(模型需实现INotifyPropertyChanged),过滤集合会自动更新,直接绑定到UI即可。

方案3:手动维护过滤后的ObservableCollection

若不想引入额外库,可手动创建过滤后的ObservableCollection,同时监听源集合变化和项的属性变化:

private ObservableCollection<YourModel> _sourceCollection;
private ObservableCollection<YourModel> _filteredCollection;
public ObservableCollection<YourModel> FilteredCollection => _filteredCollection;

public YourViewModel()
{
    _sourceCollection = new ObservableCollection<YourModel>();
    // 初始化过滤集合
    _filteredCollection = new ObservableCollection<YourModel>(
        _sourceCollection.Where(p => !p.deleted));
    
    // 监听源集合的增删改变化
    _sourceCollection.CollectionChanged += SourceCollection_CollectionChanged;
    
    // 给每个已存在的项监听deleted属性变化
    foreach (var item in _sourceCollection)
    {
        if (item is INotifyPropertyChanged notifyItem)
        {
            notifyItem.PropertyChanged += Item_PropertyChanged;
        }
    }
}

private void SourceCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
            foreach (YourModel item in e.NewItems)
            {
                if (!item.deleted)
                    _filteredCollection.Add(item);
                if (item is INotifyPropertyChanged notifyItem)
                {
                    notifyItem.PropertyChanged += Item_PropertyChanged;
                }
            }
            break;
        case NotifyCollectionChangedAction.Remove:
            foreach (YourModel item in e.OldItems)
            {
                _filteredCollection.Remove(item);
                if (item is INotifyPropertyChanged notifyItem)
                {
                    notifyItem.PropertyChanged -= Item_PropertyChanged;
                }
            }
            break;
        case NotifyCollectionChangedAction.Reset:
            _filteredCollection.Clear();
            foreach (var item in _sourceCollection.Where(p => !p.deleted))
            {
                _filteredCollection.Add(item);
                if (item is INotifyPropertyChanged notifyItem)
                {
                    notifyItem.PropertyChanged += Item_PropertyChanged;
                }
            }
            break;
    }
}

private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == nameof(YourModel.deleted))
    {
        var item = sender as YourModel;
        if (item.deleted && _filteredCollection.Contains(item))
        {
            _filteredCollection.Remove(item);
        }
        else if (!item.deleted && !_filteredCollection.Contains(item))
        {
            _filteredCollection.Add(item);
        }
    }
}

该方案适合自定义逻辑较多的场景,但需注意内存泄漏问题,ViewModel销毁时要解绑相关事件。


内容的提问来源于stack exchange,提问作者Denis De Pauli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 22:36:24