gpt4 book ai didi

c# - 如何为集合设计多重过滤器

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:48:54 25 4
gpt4 key购买 nike

我的模型:

public class Person
{
public string Name { get; set; }
public bool Sex { get; set; }
public string Country { get; set; }
}

在我的 WPF 应用程序中,我想将一个列表绑定(bind)到 DataGridControl,该 View 还支持按性别和国家筛选。

我当前的解决方案是创建一个 List PersonList 来存储所有数据,并创建另一个 List PersonBindingList 来存储应该在 UI 中显示的数据。当用户检查过滤器并单击“确定”时,使用 Linq 从 PersonList 查询并将结果分配给 PersonBindingList 以更新 UI。

但这应该维护两个列表。另外,我不想每次用户更改过滤条件时都加载数据,因为数据量非常大,加载速度很慢。还有其他解决方案吗?还有一点,Sex 和 Country 可以自由组合。

谢谢

最佳答案

如果你想在客户端过滤数据,ICollectionView (特别是 ListCollectionView)是您想要的:

public class ViewModel
{
// this is a property for filtering
public bool Sex
{
get { ... }
set
{
if (_sex != value)
{
_sex = value;
OnPropertyChanged();
PersonListView.Refresh();
}
}
}

// this is a property for filtering too
public string Country
{
// call PersonListView.Refresh in setter, as in Sex property setter
}

// this is a property for binding to DataGrid
public ICollectionView PersonListView
{
get
{
if (_personListView == null)
{
_personList = LoadPersons();
_personListView = new ListCollectionView(_personList)
{
Filter = p => ShouldViewPerson((Person)p);
}
}
return _personListView;
}
}

private bool ShouldViewPerson(Person p)
{
// implement filtering logic here;
// e.g.:
return p.Country.StartsWith(Country) && p.Sex == Sex;
}

private ListCollectionView _personListView;
private List<Person> _personList;
}

Collection View 是某种投影,用于排序、过滤和分组源集合/序列。您可以将它们视为 LINQ 的 WhereGroupByOrderBySelect 方法的组合,这将是应用于将绑定(bind)到 View 的源集合和结果序列。

默认情况下,如果您从 View 模型中公开一些集合,数据绑定(bind)引擎会为您创建默认的 Collection View 。但是如果你想获得自定义行为,比如过滤,你可以自己构建 Collection View 并公开它而不是集合。

I don't want to load data every times when user change filter conditions, because the data volumne is very huge, the loading speed is very slow

如果可以,请考虑在服务器端进行过滤。客户端过滤在内存中执行,可能会消耗大量系统资源。

更新

如果您希望从过滤列表中选择多个国家/地区,您可以将标量 Country 属性替换为 Countries 集合并重新编写过滤逻辑。像这样:

// this is a filter item
public class CountryFilterItem : INotifyPropertyChanged
{
public string CountryName { ... }
public bool IsChecked { ... }
}

public class ViewModel
{
// this property is a replacement for "Country";
// bind it to some ItemsControl is the filter view
public IEnumerable<CountryFilterItem> Countries
{
get { return _countries; }
}

// fill filter somewhere;
// when filling, subscribe on `PropertyChanged` event of each item;
// when user will change IsChecked for item, you'll update filter:
//
// var country = new Country { CountryName = "Zimbabwe" };
// country.PropertyChanged += (sender, args) =>
// {
// if (propertyName == "IsChecked")
// {
// PersonListView.Refresh();
// }
// };
// _countries.Add(country);
private List<CountryFilterItem> _countries;

// filtering logic
private bool ShouldViewPerson(Person p)
{
// implement filtering logic here;
// e.g.:
return _countries.Any(_ => _.IsChecked && _.CountryName == p.Country) && p.Sex == Sex;
}

// other code here...
}

关于c# - 如何为集合设计多重过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34505787/

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