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

.NET Maui实现无额外内存分配的ObservableCollection过滤方案问询

解决方案:基于ICollectionView实现无内存重分配的即时过滤

核心思路

利用.NET原生的ICollectionView接口,在原始ObservableCollection之上提供过滤能力——无需重新创建集合,同时完整保留原始集合的可观测特性,ListView/CollectionView可直接绑定该视图作为数据源。

具体实现步骤

1. 定义ViewModel结构

在ViewModel中维护原始数据集合和对应的ICollectionView实例,同时实现搜索文本绑定与过滤逻辑:

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;

public class MainViewModel : INotifyPropertyChanged
{
    // 原始数据集合,保留可观测特性
    private ObservableCollection<ItemModel> _originalItems;
    public ObservableCollection<ItemModel> OriginalItems
    {
        get => _originalItems;
        set
        {
            _originalItems = value;
            OnPropertyChanged(nameof(OriginalItems));
            // 初始化视图并绑定过滤方法
            ItemsView = CollectionViewSource.GetDefaultView(OriginalItems);
            ItemsView.Filter += FilterItems;
        }
    }

    // 绑定到列表控件的视图
    private ICollectionView _itemsView;
    public ICollectionView ItemsView
    {
        get => _itemsView;
        set
        {
            _itemsView = value;
            OnPropertyChanged(nameof(ItemsView));
        }
    }

    // 搜索文本绑定属性
    private string _searchText;
    public string SearchText
    {
        get => _searchText;
        set
        {
            _searchText = value;
            OnPropertyChanged(nameof(SearchText));
            // 搜索文本变化时触发过滤刷新
            ItemsView?.Refresh();
        }
    }

    // 自定义过滤逻辑
    private bool FilterItems(object item)
    {
        if (string.IsNullOrWhiteSpace(SearchText))
            return true;

        if (item is ItemModel model)
        {
            // 根据业务需求调整匹配规则,支持多字段、大小写忽略等
            return model.Name.IndexOf(SearchText, StringComparison.OrdinalIgnoreCase) >= 0
                || model.Description.IndexOf(SearchText, StringComparison.OrdinalIgnoreCase) >= 0;
        }
        return false;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

// 示例数据模型
public class ItemModel
{
    public string Name { get; set; }
    public string Description { get; set; }
}

2. XAML绑定配置

将ListView的ItemsSource绑定到ViewModel的ItemsView,SearchBar绑定到SearchText:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:YourProjectNamespace"
             x:Class="YourProjectNamespace.MainPage">
    <ContentPage.BindingContext>
        <vm:MainViewModel />
    </ContentPage.BindingContext>

    <VerticalStackLayout>
        <SearchBar Text="{Binding SearchText, Mode=TwoWay}"
                   Placeholder="输入关键词搜索"/>
        <ListView ItemsSource="{Binding ItemsView}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <VerticalStackLayout Padding="10">
                            <Label Text="{Binding Name}" FontSize="Large"/>
                            <Label Text="{Binding Description}" FontSize="Small" TextColor="Gray"/>
                        </VerticalStackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </VerticalStackLayout>
</ContentPage>

3. 关键特性说明

  • ICollectionView基于原始ObservableCollection工作,过滤仅调整项的可见性,不会触发集合内存重分配
  • 原始集合的增删改操作会自动同步到视图,完整保留可观测特性
  • 过滤逻辑可灵活扩展,支持正则匹配、多字段组合等复杂规则
  • 若使用Maui推荐的CollectionView,绑定方式完全一致,仅需替换ListView标签即可

内容的提问来源于stack exchange,提问作者YMC

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:11:32