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