C# 如何在ObjectListView中筛选多个子项
因此,我试图以编程方式将ModelFilter添加到ObjectListView中,该视图将分别查看两个(或更多)列和每个列上的筛选器。目前,我认为ObjectListView只支持一个过滤器,但我可能在代码/文档中遗漏了一些东西 例如,我打算使用的过滤器之一是查看“Active”列,该列的值为“A”或“T”。另一列是主管名称。因此,我想查找Supervisor name=“Smith”和Active=“A”所在的所有条目 我可以使用TextMatchFilter让过滤器分别为这两个选项之一工作,但无法找出如何让这两个选项同时工作 我看到的一个小问题是,如果Supervisor名称包含“A”,那么使用标准过滤器将返回整行。如果我不想查看列,我可以通过编程将列的Searchable属性设置为false,然后在过滤完列表后将其重新打开,从而绕过了这个问题。然而,我有一种感觉,如果我打开主管栏的Searchable,我会得到不想要的结果 是否有人知道如何让筛选器在多个列上工作,只为每个筛选器使用指定的列 (我没有示例代码可以帮助您解决这个问题。但是,如果您真的想查看我的过滤代码,我很乐意添加它;但是,它是在VB中) 当前代码-查看用户选择的值(searchMeth),并启用对该列的搜索。然后它搜索在txtSearch框中输入的内容。然而,除此之外,我还想为主管添加一个额外的过滤器。(见安达索评论)C# 如何在ObjectListView中筛选多个子项,c#,.net,vb.net,winforms,objectlistview,C#,.net,Vb.net,Winforms,Objectlistview,因此,我试图以编程方式将ModelFilter添加到ObjectListView中,该视图将分别查看两个(或更多)列和每个列上的筛选器。目前,我认为ObjectListView只支持一个过滤器,但我可能在代码/文档中遗漏了一些东西 例如,我打算使用的过滤器之一是查看“Active”列,该列的值为“A”或“T”。另一列是主管名称。因此,我想查找Supervisor name=“Smith”和Active=“A”所在的所有条目 我可以使用TextMatchFilter让过滤器分别为这两个选项之一工作
olvEmps.UseFiltering = True
OlvColumn1.Searchable = False
OlvColumn2.Searchable = False
OlvColumn4.Searchable = False
OlvColumn3.Searchable = False
OlvColumn5.Searchable = False
Select Case searchMeth
Case "Name"
OlvColumn1.Searchable = True
Case "Employee Number"
OlvColumn2.Searchable = True
Case "Department"
OlvColumn3.Searchable = True
End Select
olvEmps.OwnerDraw = True
Dim tFilter As BrightIdeasSoftware.TextMatchFilter = BrightIdeasSoftware.TextMatchFilter.Contains(olvEmps, txtSearch.Text)
'andalso olvColumn5 = supeName?
olvEmps.ModelFilter = tFilter
olvEmps.DefaultRenderer = New BrightIdeasSoftware.HighlightTextRenderer(tFilter)
OlvColumn1.Searchable = True
OlvColumn2.Searchable = True
OlvColumn3.Searchable = True
OlvColumn4.Searchable = True
OlvColumn5.Searchable = True
虽然我还并没有完全理解你们的交易,但我会尝试一下,这是LINQKit组件的一部分,你们可以下载
这样,在多个列上的筛选将变得容易。也许一旦您的源集合已被过滤,您可能会考虑重置<代码> ObjistListVIEW/COD>控件的绑定。
大体上,我会做以下几点:public class FilterCriterion {
public bool HasEmployeeName { get { return !string.IsNullOrWhiteSpace(EmployeeName); } }
public bool HasEmployeeNumber { get { return !string.IsNullOrWhiteSpace(EmployeeNumber); } }
public bool HasDepartment { get { return !string.IsNullOrWhiteSpace(Department); } }
public string EmployeeName { get; set; }
public string EmployeeNumber { get; set; }
public string Department { get; set; }
}
FilterCriterion类应用于针对您的数据源、集合或任何内容应用任何您想要的过滤器
var employees = LoadEmployeesFromUnderlyingDataStore();
var criterion = new FilterCriterion();
switch(searchMeth) {
case "Name": filter.EmployeeName = "the name to filter by"; break;
case "EmployeeNumber": filter.EmployeeNumber = "the number to filter by"; break;
case "Department": filter.Department = "the department to filter by"; break;
}
var filter = PredicateBuilder.True<Employee>(); // assuming you have an employee class.
if (criterion.HasEmployeeName)
filter.And(e => e.Name.ContainsLike(criterion.EmployeeName));
if (criterion.HasEmployeeNumber)
filter.And(e => e.EmployeeNumber.ContainsLike(criterion.EmployeeNumber));
if (criterion.HasDepartment)
filter.And(e => e.Department.ContainsLike(criterion.Department));
var filteredEmployees = employees.Where(filter);
// Supply your ObjectListView the way you're used to and this shall function.
我希望这能有所帮助,否则请告诉我我对你的问题的误解,我们将一起努力解决这个问题
如果你需要这段代码的VB版本,我会尽量用我的VB知识来翻译
这段代码是按原样提供的,除了两种字符串扩展方法外,没有经过测试。我确信PredicateBuilder解决方案会起作用,但是
ObjectListView
已经提供了一个更简单的解决方案
TextMatchFilter
可以通过columns
属性限制搜索的列。将此设置为要考虑的列数组。
TextMatchFilter filter1 = TextMatchFilter.Contains(olvEmps, txtSearch.Text)
filter1.Columns = new [] { this.olvColumn1, this.olvColumn2 };
您可以使用CompositeAllFilter
组合两个过滤器,以匹配两个或多个其他过滤器
this.olvEmps.ModelFilter = new CompositeAllFilter(new List<IModelFilter> { filter1, filter2 });
this.olvEmps.ModelFilter=newcompositealFilter(新列表{filter1,filter2});
一定要添加过滤代码,以便更容易获得帮助。=)无论是VB还是C#,只要你用好的语言标记你的问题,那么回答者就能用所需的语言为你提供帮助,无论是VB还是C#代码已添加,标记已更改。谢谢@WillI,我会看看我能用你的代码样本做些什么。我希望这会有帮助!=)我刚刚编辑了我的答案,以便根据您提供的代码示例向您提供更多详细信息。我将查看PredicateBuilder。不幸的是,我对LINQ还不熟悉,但根据我对上述解决方案的理解,似乎我必须添加一些数据绑定?目前,我使用ObjectListView的SetObjects方法来使用对象集合。另外,我不希望最终用户点击一列进行过滤;我将使用平铺视图,它不会;我甚至不能提供列标题来实现这一点。我会告诉你PredicateBuilder是否会这样做。哦,我想我可以在我的原始集合上使用lambdas,然后使用新的筛选集合再次填充ObjectListView。不过,这似乎是一个解决办法。您完全可以使用lambda表达式和Linq的强大功能来帮助您。请给我一些时间,以便我能为您想出一些办法,看看是否有帮助。=)+1如何通过objectlistview创建者建议的本机三行解决方案
this.olvEmps.ModelFilter = new CompositeAllFilter(new List<IModelFilter> { filter1, filter2 });