WPF 使用ICollectionView过滤表格数据

ICollectionView接口

是一个用于提供数据视图的类,它允许你对数据进行排序、筛选和分组。可以通过静态方法CollectionViewSource.GetDefaultView(object)获取。

MSDN接口说明:https://learn.microsoft.com/zh-cn/dotnet/api/system.componentmodel.icollectionview?view=windowsdesktop-8.0

代码演示

MVVM框架使用CommunityToolkit.MVVM,UI界面框架使用MaterialDesignThemes,生成测试数据使用Bogus

View代码为:

<Window
    x:Class="WPFTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:be="http://schemas.microsoft.com/xaml/behaviors"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WPFTest"
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
 <Grid>
 <Grid.RowDefinitions>
 <RowDefinition Height="auto"  />
 <RowDefinition Height="*"  />
 </Grid.RowDefinitions>
 <TextBox
            Grid.Row="0"
            Margin="5"
            Text="{Binding SearchContent, UpdateSourceTrigger=PropertyChanged}"  />
 <DataGrid
            x:Name="DataGrid"
            Grid.Row="1"
            Margin="5"
            materialDesign:DataGridAssist.CellPadding="4 2 2 2"
            materialDesign:DataGridAssist.ColumnHeaderPadding="4 2 2 2"
            AutoGenerateColumns="True"
            Background="White"
            GridLinesVisibility="All"
            HorizontalScrollBarVisibility="Visible"
            IsReadOnly="True"
            ItemsSource="{Binding CollectionView}"
            SelectionMode="Single"
            VerticalScrollBarVisibility="Visible">
 </DataGrid>
 </Grid>
</Window>

ViewModel部分代码为:

using CommunityToolkit.Mvvm.ComponentModel;
using Bogus;
using System.ComponentModel;
using System.Windows.Data;
  
namespace WPFTest
{
 public  class MainViewModel : ObservableRecipient
    {
 private List<DataModel> list = new List<DataModel>();
  
        //数据表格显示内容,动态加载不同类型的内容
 private ICollectionView collectionView;
  
 public ICollectionView CollectionView
        {
 get => collectionView;
 set => SetProperty(ref collectionView, value);
        }
  
        //搜索内容
 private  string searchContent = string.Empty;
  
 public  string SearchContent
        {
 get => searchContent;
 set
            {
                if (SetProperty(ref searchContent, value))
                {
                    CollectionView.Refresh();
                }
            }
        }
  
        public MainViewModel()
        {
            InitTestData();
            CollectionView = CollectionViewSource.GetDefaultView(list);
CollectionView.Filter = new Predicate<object>(OnFilterMovie);
        }
  
/// <summary>
        /// 过滤方法
/// </summary>
/// <param  name="item"></param>
/// <returns></returns>
private bool OnFilterMovie(object item)
        {
 if (string.IsNullOrEmpty(SearchContent) || item == null || list == null || list.Count <= 0)
            {
 return  true;
            }
 else
            {
DataModel model = item as DataModel;
 return model.Name.IndexOf(SearchContent, StringComparison.InvariantCultureIgnoreCase) >= 0;
            }
        }
  
private void InitTestData()
        {
            list.Clear();
Randomizer.Seed = new Random(123456);
 var customerGenerator = new Faker<DataModel>()
                .RuleFor(c => c.Id, Guid.NewGuid())
                .RuleFor(c => c.Name, f => f.Company.CompanyName())
                .RuleFor(c => c.Address, f => f.Address.FullAddress())
                .RuleFor(c => c.City, f => f.Address.City())
                .RuleFor(c => c.Country, f => f.Address.Country())
                .RuleFor(c => c.ZipCode, f => f.Address.ZipCode())
                .RuleFor(c => c.Phone, f => f.Phone.PhoneNumber())
                .RuleFor(c => c.Email, f => f.Internet.Email());
            list = customerGenerator.Generate(100);
        }
    }
}

Model代码为:

namespace WPFTest
{
 public  class DataModel
    {
 public Guid Id { get; set; } =  new Guid();
 public  string Name { get; set; } =  string.Empty;
 public  string Address { get; set; } =  string.Empty;
 public  string City { get; set; } =  string.Empty;
 public  string Country { get; set; } =  string.Empty;
 public  string ZipCode { get; set; } =  string.Empty;
 public  string Phone { get; set; } =  string.Empty;
 public  string Email { get; set; } =  string.Empty;
    }
}

示例程序界面由文本框和表格组成,文本框过滤名称,后台绑定数据一发生变化则刷新CollectionView更新界面,表格实际绑定为CollectionView,数据部分可以直接用List而不用ObservableCollection,过滤方法为

CollectionView.Filter =  new Predicate<object>(OnFilterMovie);

将过滤逻辑OnFilterMovie绑定至Filter上,在OnFilterMovie中判断实际的返回结果

运行效果如下:


回顾

CollectionView就是一个视图类,它的实例代表了一个视图类实例,视图可以用来做集合对象显示的相关操作(分组,排序,过滤,导航等)。视图的优点有:对视图的分组,过滤等等操作不会影响到源集合本身;一个集合可以有多个不同的视图,源集合的改变有能力通知到它所有的视图(前提是源集合实现了INotifyCollectionChanged接口)。

posted @ 2024-07-23 18:16  说不出来  阅读(108)  评论(0编辑  收藏  举报