Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.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# WPF MVVM如何在ICollectionView中组合多个过滤器_C#_Wpf_Mvvm - Fatal编程技术网

C# WPF MVVM如何在ICollectionView中组合多个过滤器

C# WPF MVVM如何在ICollectionView中组合多个过滤器,c#,wpf,mvvm,C#,Wpf,Mvvm,我有一个问题似乎相当简单,但我似乎有一个问题: 我有一个包含一些数据的数据网格: <DataGrid ItemsSource="{Binding Candidates, IsAsync=True}" AutoGenerateColumns="False" EnableColumnVirtualization="True" Enab

我有一个问题似乎相当简单,但我似乎有一个问题:

我有一个包含一些数据的数据网格:

            <DataGrid ItemsSource="{Binding Candidates, IsAsync=True}" 
                      AutoGenerateColumns="False" 
                      EnableColumnVirtualization="True" 
                      EnableRowVirtualization="True"
                      VirtualizingStackPanel.VirtualizationMode="Standard"
                      VirtualizingStackPanel.IsVirtualizing="True"
                      CanUserAddRows="false">

                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding Firstname}" Header="Imię" />
                    <DataGridTextColumn Binding="{Binding Lastname}" Header="Nazwisko" />
                    <DataGridTextColumn Binding="{Binding commendation.Name}" Header="Polecenie" />
  </DataGrid.Columns>
</DataGrid>
过滤器看起来像:

    public void FilterFirstname(object obj)
    {
        this.Candidates.Filter += item =>
        {
            Candidate candidate = item as Candidate;
            return candidate.Firstname.Contains(obj.ToString());
        };

        this.Candidates.Refresh();
    }

    public void FilterLastname(object obj)
    {
        this.Candidates.Filter += item =>
        {
            Candidate candidate = item as Candidate;

            if(string.IsNullOrWhiteSpace(candidate.Lastname))
            {
                return false;
            }

            return candidate.Lastname.Contains(obj.ToString());
        };

        this.Candidates.Refresh();
    }

    public void FilterCommendation(object obj)
    {
        this.Candidates.Filter += item =>
        {
            Candidate candidate = item as Candidate;

            if (string.IsNullOrWhiteSpace(candidate.commendation.Name))
            {
                return false;
            }

            return candidate.commendation.Name.Contains(obj.ToString());
        };

        this.Candidates.Refresh();
    }
现在,这基本上是按预期工作,但它在每个列上分别工作,因此,如果我键入name,它将筛选我的姓名,如果我键入last name,它将筛选我的last name,但它将覆盖name,因此我不会得到name和last name的精确匹配,我希望聚合这些筛选器


有什么方法可以聚合这些过滤器吗

为什么它不起作用?

在每个
filterCommandation
FilterLastname
FilterFirstname
上,您正在向
此.Candidates.Filter添加另一个代理。它们都将在刷新时执行,但只返回最后一次委托的结果。考虑下面的例子:

Predicate<int> tmp = i => true;
tmp += i => i != 0;

Assert.AreEqual(true, tmp(1));
Assert.AreEqual(false, tmp(0));

filters属性是什么样子的?我刚刚添加了
filters
字段的定义。要将其用于“或”过滤器,我在FilterCandidates的聚合方法中更改了“&&”到“||”,将“true”改为“false”。在聚合之前还必须添加一行:filters.count==0->returntrue
Predicate<int> tmp = i => true;
tmp += i => i != 0;

Assert.AreEqual(true, tmp(1));
Assert.AreEqual(false, tmp(0));
    Dictionary<string, Predicate<Candidate>> filters
        = new Dictionary<string, Predicate<Candidate>>();

    public CatalogViewModel()
    {
        ...

        Candidates.Filter = FilterCandidates;
    }

    private bool FilterCandidates(object obj)
    {
        Candidate c = (Candidate)obj;
        return filters.Values
            .Aggregate(true,
                (prevValue, predicate) => prevValue && predicate(c));
    }
    public void FilterFirstname(object obj)
    {
        string val = obj.ToString();
        AddFilterAndRefresh(
            "FirstName",
            candidate => candidate.Firstname.Contains(val));
    }

    public void FilterLastname(object obj)
    {
        string val = obj.ToString();
        AddFilterAndRefresh(
            "FirstName",
            candidate => !string.IsNullOrWhiteSpace(candidate.Lastname) && candidate.Lastname.Contains(val));
    }

    public void ClearFilters()
    {
        filters.Clear();
        Candidates.Refresh();
    }

    public void RemoveFilter(string filterName)
    {
        if (filters.Remove(filterName))
        {
            Candidates.Refresh();
        }
    }

    private void AddFilterAndRefresh(string name, Predicate<Candidate> predicate)
    {
        filters.Add(name, predicate);
        Candidates.Refresh();
    }