Предположим, что у меня есть класс Node
public class Node
{
public string Name;
public ObservableCollection<Node> SubNodes;
}
и создал следующий xaml для визуализации коллекции объектов Node:
<TreeView Name="Tree">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="myNamespace:Node"
ItemsSource="{Binding Path=SubNodes}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
в кодовом коде я пишу что-то вроде
Tree.ItemsSource = my_Observable_Collection_Of_Nodes;
и наслаждайтесь результатом.
Теперь я хочу применить свою собственную функцию фильтрации (например, "MyFilterFun") ко всем узлам в древовидной структуре. С этой целью я изменил HierarchicalDataTemplate на что-то вроде
<HierarchicalDataTemplate DataType="myNamespace:MyClass">
<HierarchicalDataTemplate.ItemsSource>
<Binding>
<Binding.Source>
<CollectionViewSource Source="{Binding Path=SubNodes}"
Filter="MyFilterFun"/>
</BindingSource>
</Binding>
<HierarchicalDataTemplate.ItemsSource>
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
К сожалению, это не работает, "MyFilterFun" никогда не вызывается. Итак, каков правильный способ сделать это?
Это можно сделать, используя ICollectionView. Из вашего ObservableCollection вы можете сделать что-то вроде:
SubNodesCollectionView = CollectionViewSource.GetDefaultView(SubNodes);
SubNodesCollectionView.Filter = (param) =>
{
return true;
};
Затем привяжите к SubNodesCollectionView вместо SubNodes. Лямбда-обработчик будет методом, который вы можете указать для фильтрации каждого вместо того, чтобы просто возвращать true.
CollectionViewSource
илиICollectionView
в базовом исходном классе иICollectionView
с этим свойством.