Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在ObjectListView中筛选多个子项_C#_.net_Vb.net_Winforms_Objectlistview - Fatal编程技术网

C# 如何在ObjectListView中筛选多个子项

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让过滤器分别为这两个选项之一工作

因此,我试图以编程方式将ModelFilter添加到ObjectListView中,该视图将分别查看两个(或更多)列和每个列上的筛选器。目前,我认为ObjectListView只支持一个过滤器,但我可能在代码/文档中遗漏了一些东西

例如,我打算使用的过滤器之一是查看“Active”列,该列的值为“A”或“T”。另一列是主管名称。因此,我想查找Supervisor name=“Smith”和Active=“A”所在的所有条目

我可以使用TextMatchFilter让过滤器分别为这两个选项之一工作,但无法找出如何让这两个选项同时工作

我看到的一个小问题是,如果Supervisor名称包含“A”,那么使用标准过滤器将返回整行。如果我不想查看列,我可以通过编程将列的Searchable属性设置为false,然后在过滤完列表后将其重新打开,从而绕过了这个问题。然而,我有一种感觉,如果我打开主管栏的Searchable,我会得到不想要的结果

是否有人知道如何让筛选器在多个列上工作,只为每个筛选器使用指定的列

(我没有示例代码可以帮助您解决这个问题。但是,如果您真的想查看我的过滤代码,我很乐意添加它;但是,它是在VB中)

当前代码-查看用户选择的值(searchMeth),并启用对该列的搜索。然后它搜索在txtSearch框中输入的内容。然而,除此之外,我还想为主管添加一个额外的过滤器。(见安达索评论)

    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>控件的绑定。

大体上,我会做以下几点:

  • 加载数据
  • 通过数据绑定显示
  • 单击一列进行筛选后,调用将应用谓词的“filter”方法
  • 使用新的筛选集合重新绑定控件
  • 请参阅前面提供的链接处的PredicateBuilder文档。此处演示了构建动态过滤器的另一个示例:“对于我实现的搜索引擎”

    在我的例子中,过滤器直接应用于数据库结果。此外,它甚至可以用于内存数据,因为它是基于Linq的

    我相信,当您发布用于过滤信息的代码示例时,我将能够提供进一步的帮助

    编辑#1

    在我阅读了提供的代码示例之后,以下是我认为可以解决问题的方法。至于可搜索属性,我对这种方法并不熟悉,因此我可能会从您的代码中漏掉一些重要的内容,如果是这样,请随意指出我可能漏掉的内容。=)

    注意,我假设您的所有数据都是字符串,因为我正在验证您的数据是null还是空白。此外,在我看来,过滤结果集就是只显示符合特定标准的记录。你不想看到什么不符合标准。它与SQL中的WHERE子句相同

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