gpt4 book ai didi

c# - 基于 CheckBoxes 过滤 ObservableCollection

转载 作者:太空宇宙 更新时间:2023-11-03 23:25:09 25 4
gpt4 key购买 nike

我有一个 DataGrid,其中包含许多 Jobs。这些 Jobs 中的每一个都有一个与之关联的员工,我想根据这些工作中的员工进行过滤。所以我有四个 CheckBoxes;

<CheckBox x:Name="employeeARad" Content="EmployeeA" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="18" Margin="7,0,0,5"/>
<CheckBox x:Name="employeeBRad" Content="EmployeeD" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="18" Margin="7,5,0,5"/>
<CheckBox x:Name="employeeCRad" Content="EmployeeC" HorizontalAlignment="Left" Margin="7,5,0,5" VerticalAlignment="Top" FontSize="18"/>
<CheckBox x:Name="employeeDRad" Content="EmployeeD" HorizontalAlignment="Left" Margin="7,5,0,5" VerticalAlignment="Top" FontSize="18"/>

我从我的数据库中检索并填充数据的ObservableCollection。然后,我使用以下方法将此集合绑定(bind)到我的 DataGrid:dataGrid.ItemsSource = _jobDataService.GetJobList();。正如我之前所说,每项工作都有其模型的一部分与 Employee 相关联。这是 Job 的模型;

class JobModel
{
public int CaseNumber { get; set; }
public string EmployeeName { get; set; }
public string CaseNotes { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateDeadline { get; set; }
public string CaseClient { get; set; }
}

我的真正问题是如何根据 CheckBoxes 的选择过滤绑定(bind)到 DataGrid 的这个集合?

最佳答案

当您绑定(bind)到 WPF 中的集合时,派生自 ICollectionView 的对象是在幕后创建的。该接口(interface)支持通过使用各种属性对集合进行排序和过滤。

我通常做的是有一个 ObservableCollection<T>分配给一个私有(private)字段,其中包含所有数据。然后我有一个类型为 ICollectionView 的相应公共(public)属性,我对其应用任何排序或过滤条件。

以下是一个简单窗口的 XAML,其中包含工作列表,以及用于按员工姓名筛选列表的复选框。为简单起见,我在职位列表中显示员工姓名:

<Window x:Class="StackOverflow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DockPanel Margin="10">
<StackPanel x:Name="_employees" DockPanel.Dock="Top">
<CheckBox Content="Fred" IsChecked="True" Click="OnCheckBoxClick" />
<CheckBox Content="Wilma" IsChecked="True" Click="OnCheckBoxClick" />
<CheckBox Content="Barney" IsChecked="True" Click="OnCheckBoxClick" />
<CheckBox Content="Betty" IsChecked="True" Click="OnCheckBoxClick" />
</StackPanel>
<ListBox ItemsSource="{Binding JobsCollectionView}"
DisplayMemberPath="EmployeeName" Margin="0,10,0,0" />
</DockPanel>
</Window>

这是此窗口的隐藏代码(我重复使用了您现有的 JobModel 类,因此此处未显示该代码):

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

namespace StackOverflow
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();

_jobs = new ObservableCollection<JobModel>
{
new JobModel { EmployeeName = "Fred" },
new JobModel { EmployeeName = "Wilma" },
new JobModel { EmployeeName = "Fred" },
new JobModel { EmployeeName = "Barney" },
new JobModel { EmployeeName = "Betty" },
};

JobsCollectionView = CollectionViewSource.GetDefaultView(_jobs);
DataContext = this;
}

readonly ObservableCollection<JobModel> _jobs;

public ICollectionView JobsCollectionView { get; private set; }

void OnCheckBoxClick(object sender, RoutedEventArgs e)
{
var checkedEmployees = new HashSet<string>();
foreach (CheckBox checkBox in _employees.Children)
{
if (checkBox.IsChecked == true)
{
checkedEmployees.Add((string) checkBox.Content);
}
}

JobsCollectionView.Filter =
job => checkedEmployees.Contains((job as JobModel).EmployeeName);
}
}
}

可以看到私有(private)_jobs持有工作和公众集合的领域JobsCollectionView提供访问 ICollectionView 的属性实现(CollectionViewSource.GetDefaultView 方法用于获取它)。

每个 CheckBox 控件都有一个 Click 事件处理程序(它们都指向相同的方法),它简单地遍历复选框以构建一个员工姓名列表当前“选中”( checkedEmployees ),然后设置 Filter Collection View 的属性以应用适当的过滤逻辑。基本上,过滤器是一个委托(delegate),它从 View 中获取一个项目(在您的例子中是一个 JobModel 对象)并返回一个 bool 值,该值指示该特定对象是否应包含在 View 中。在这里,我只是检查工作中的员工姓名是否包含在过滤后的员工姓名集中。

需要注意的一件事是 ICollectionView 的性能对于非常大的列表,排序和过滤可能是一个问题,在这种情况下,您可能需要通过从原始数据集中构建一个全新的列表来进行排序/过滤。不过,我会先尝试使用 Collection View 方法,然后看看效果如何。

关于c# - 基于 CheckBoxes 过滤 ObservableCollection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34042389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com