当前位置:   article > 正文

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

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

    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; }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

DataGirdView

<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>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
    public partial class DataGirdView : UserControl
    {
        
        public DataGirdView()
        {
            InitializeComponent();
            //将主要的代码逻辑放在ViewModel里面
            ViewModel.DataGirdView = this;
        }

 
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

DataGridViewModel

 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();
         };
         
     }

 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

实现效果

在这里插入图片描述

DataGrid直接绑定CollectionView

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

xaml

<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>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

ViewModel

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);
                }
            };

        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

总结

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/169896
推荐阅读
相关标签
  

闽ICP备14008679号