WPF 【十月的寒流】学习笔记(1):DataGrid过滤

文章目录

相关链接

十月的寒流


在 WPF 中制作 DataGrid 的数据筛选功能
WPF 中如何制作 DataGrid 的分页功能

代码仓库

我为了方便展示源代码,我将代码提交到了代码仓库里面

B站【十月的寒流】对应课程的代码 Github仓库

前言

为了深入的重新学习WPF的基础知识,打算从【B站:十月的寒流】这位大佬上面去学习WPF的相关的知识。我其实更推荐大家去看原视频的相关教程内容。

环境

  • visual studio 2022
  • .net core 8.0
  • windows11

DataGrid 数据筛选

项目配置

如何使用我这里就不展开说明了

WPF CommunityToolkit.Mvvm
WPF CommunityToolkit.Mvvm Messenger通讯

WPF-UI HandyControl 简单介绍
WPF-UI HandyControl 控件简单实战+IconPacks矢量图导入

Bogus,.NET生成批量模拟数据

使用原理

WPF DataGrid 数据过滤
ICollectionView让MVVM更简单
微软官方文档|ICollectionView 接口

这里不得不提到微软的WPF文档了,写了和没写差不多。

实现原理就是微软为了方便对数据进行分组、排序和筛选。给ItemSorce添加了ICollectionView 专门用于干这个。然后我们可以对ICollectionView添加规则,Ture就是需要,False就是不需要。

主要代码(详细代码可以看我的GitHub仓库)

Models.Person

csharp 复制代码
    public class Person
    {
        public int Id { get; set; }

        public string FullName { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public DateTime BirthDay { get; set; }
    }

DataGirdView

xml 复制代码
<UserControl x:Class="DataGrid_Filter.Views.DataGirdView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:DataGrid_Filter.Views"
             xmlns:hc="https://handyorg.github.io/handycontrol"
             xmlns:viewModels="clr-namespace:DataGrid_Filter.ViewModels"
             mc:Ignorable="d"
             d:DesignHeight="450"
             d:DesignWidth="800">
    <UserControl.DataContext>
        <viewModels:DataGridViewModel  x:Name="ViewModel" />
    </UserControl.DataContext>
    <DockPanel LastChildFill="True">

        <StackPanel DockPanel.Dock="Bottom"
                    Orientation="Horizontal"
                    Margin="5">
            <Button Command="{Binding AddItemCommand}"
                    Content="AddNewItem" />
            <!--添加名称,方便绑定-->
            <hc:TextBox Text="{Binding FilterStr,UpdateSourceTrigger=PropertyChanged}"
                        hc:InfoElement.Placeholder="Filter By Name"
                        MinWidth="200"
                        Margin="5 0 0 0"
                        x:Name="FilterBox" />
        </StackPanel>
        <!--添加名称,方便绑定-->
        <DataGrid ItemsSource="{Binding PeopleList}"
                  x:Name="PeopleDataGrid">

        </DataGrid>
    </DockPanel>
</UserControl>
csharp 复制代码
    public partial class DataGirdView : UserControl
    {
        
        public DataGirdView()
        {
            InitializeComponent();
            //将主要的代码逻辑放在ViewModel里面
            ViewModel.DataGirdView = this;
        }

 
    }

DataGridViewModel

csharp 复制代码
 public partial class DataGridViewModel : ObservableObject
 {
     [ObservableProperty]
     private string title = "DataGird Tttle";

     [ObservableProperty]
     private ObservableCollection<Models.Person> peopleList = new();

     [ObservableProperty]
     private ICollectionView collectionView;

     [ObservableProperty]
     private string filterStr = "";


     private DataGrid_Filter.Views.DataGirdView dataGirdView;
     public DataGrid_Filter.Views.DataGirdView DataGirdView
     {
         get => dataGirdView;
         set {
             dataGirdView = value;
             ViewInit();
         }
     }

     public static int OrderId = 1;


     /// <summary>
     /// 生成模拟的数据
     /// </summary>
     public static Faker<Models.Person> Faker = new Faker<Models.Person>()
         .RuleFor(t => t.Id, f => OrderId++)
         .RuleFor(t => t.FirstName, f => f.Name.FirstName())
         .RuleFor(t => t.LastName, f => f.Name.LastName())
         .RuleFor(t => t.FullName, f => f.Name.FullName())
         .RuleFor(t => t.BirthDay, f => f.Date.Between(new DateTime(1990, 1, 1), new DateTime(2010, 1, 1)));

     public DataGridViewModel()
     {
         PeopleList = new ObservableCollection<Models.Person>(Faker.Generate(10));

     }

     [RelayCommand]
     public void AddItem()
     {
         var item = Faker.Generate();
         PeopleList.Add(item);
     }

     public void ViewInit()
     {
         //获取ItemSource的CollectionView
         CollectionView = CollectionViewSource.GetDefaultView(DataGirdView.PeopleDataGrid.ItemsSource);
         //给CollectionView添加过滤规则
         CollectionView.Filter = (item) =>
         {
             if (string.IsNullOrEmpty(FilterStr))
             {
                 return true;
             }
             else
             {
                 var model = item as Models.Person;
                 return model.FirstName.Contains(FilterStr) || model.LastName.Contains(FilterStr) || model.FullName.Contains(FilterStr);
             }
         };
         
         //在TextChanged的时候,实时更新
         DataGirdView.FilterBox.TextChanged += (s, e) =>
         {
             CollectionView.Refresh();
         };
         
     }

 }

实现效果

DataGrid直接绑定CollectionView

第一种方法是通过获取ItemSorce来获取CollectionView,实在是舍近求远。这次我们选择第二种方法。直接绑定设置好的CollectionView。然后我们在每次刷新输入框和改动数据的时候,主动更新绑定内容。

xaml

xml 复制代码
<UserControl x:Class="DataGrid_Filter.Views.DataGrid2View"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:DataGrid_Filter.Views"
             xmlns:viewModels="clr-namespace:DataGrid_Filter.ViewModels"
             xmlns:hc="https://handyorg.github.io/handycontrol"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.DataContext>
        <viewModels:DataGrid2ViewModel />
    </UserControl.DataContext>
    <Grid>
        <DockPanel LastChildFill="True">

            <StackPanel DockPanel.Dock="Bottom"
                        Orientation="Horizontal"
                        Margin="5">
                <Button Command="{Binding AddItemCommand}"
                        Content="AddNewItem" />
                <!--添加名称,方便绑定-->
                <hc:TextBox Text="{Binding FilterStr,UpdateSourceTrigger=PropertyChanged}"
                            hc:InfoElement.Placeholder="Filter By Name"
                            MinWidth="200"
                            Margin="5 0 0 0"
                            x:Name="FilterBox" />
            </StackPanel>
            <!--添加名称,方便绑定-->
            <DataGrid ItemsSource="{Binding CollectionView}"
                      x:Name="PeopleDataGrid">

            </DataGrid>
        </DockPanel>
    </Grid>
</UserControl>

ViewModel

csharp 复制代码
using Bogus;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DataGrid_Filter.Views;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace DataGrid_Filter.ViewModels
{
    public partial class DataGrid2ViewModel : ObservableObject
    {
        [ObservableProperty]
        private List<Models.Person> people = new List<Models.Person>();

        [ObservableProperty]
        private ICollectionView collectionView;

        private string filterStr = "";

        public string FilterStr
        {
            get
            {
                return filterStr;
            }
            set
            {
                SetProperty(ref filterStr, value);
                CollectionView.Refresh();
            }
        }


        [RelayCommand]
        public void AddItem()
        {
            var item = DataGridViewModel.Faker.Generate();
            People.Add(item);
            CollectionView.Refresh();
        }

        public DataGrid2ViewModel()
        {
            People = DataGridViewModel.Faker.Generate(10).ToList();
            CollectionView = CollectionViewSource.GetDefaultView(People);
            CollectionView.Filter = (item) =>
            {
                if (string.IsNullOrEmpty(FilterStr))
                {
                    return true;
                }
                else
                {
                    var model = item as Models.Person;
                    return model.FirstName.Contains(FilterStr) || model.LastName.Contains(FilterStr) || model.FullName.Contains(FilterStr);
                }
            };

        }
    }
}

总结

学WPF还是不能闭门造车,一定要先找网上有没有对应的方法,实在没有再自己想方法解决。【十月的寒流】的【WPF教程】确实不错,建议大家都去看一下。

相关推荐
摇滚侠1 天前
Codebuddy 官网 Codebuddy IntelliJ IDEA 插件 阅读笔记 2
java·笔记·intellij-idea
Daimuovo1 天前
盘古模型热带气旋快速增强预报评估
经验分享·笔记·其他
神明不懂浪漫1 天前
【第三章】链表
开发语言·数据结构·经验分享·笔记·链表
今儿敲了吗1 天前
Python——模块、异常、面向对象
开发语言·笔记·python
若衹如初見1 天前
一步一步学习使用LiveBindings() LiveBindings图像绑定与自定义绑定方法()
学习·命令模式
kdxiaojie1 天前
Linux 驱动研究 —— V4L2 (15)
linux·运维·笔记·学习
摇滚侠1 天前
Java 全栈开发实战教程 课程笔记 39-56
java·开发语言·笔记
fanged1 天前
udev番外--动态驱动加载(TODO)
学习
dalong101 天前
WPF:3D正八面体自动旋转
3d·wpf
醉城夜风~1 天前
HTML列表标签学习博客:有序列表、无序列表、自定义列表详解
前端·学习·html