我正在使用ICollectionView
来显示,过滤和排序TreeView
中WPF
的项目。每个树项都有自己的子项集合,以下列方式创建:
children = new ObservableCollection<MyTreeItem>();
visibleChildren = CollectionViewSource.GetDefaultView(children);
过滤包括两个步骤。第一个是遍历整个层次结构(总共约600个项目),并选择显示哪些项目以及哪些项目应该被过滤掉。
private static bool RecursiveApply(StructureTreeBaseItem root,
StructureTreeFilterInfo info) {
bool show = false;
foreach (var child in root.Children)
show &= RecursiveApply(child, info);
if (!show)
show = root.MatchesFilter(info);
root.IsFilteredOut = !show;
return show;
}
第二步是递归调用所有Refresh
上的ICollectionView
,以允许他们对更改作出反应。
root.RefreshChildren();
// ->
public void RefreshChildren() {
if (ChildrenChanged)
VisibleChildren.Refresh();
foreach (var child in VisibleChildren)
(child as StructureTreeBaseItem).RefreshChildren();
}
我有点担心这种情况的表现。我在类似的条件下进行了一些测试,事实证明,从头开始构建树结构需要大约100-150ms,应用过滤器通常花费不超过50ms,但递归调用Refresh
需要600ms甚至更多。
从我发现的情况来看,似乎每次应用过滤器而不是使用ICollectionView
功能来重建树结构时更有意义。这似乎是错的。我做的事情不是我想要的方式,也许这是ICollectionView
的普遍问题,我应该用另一种方式解决这个问题吗?
编辑 :(回应评论)
这是XAML中我的树结构的一个相关部分 - 没什么特别的:)剩下的就是纯粹的表现形式。
<TreeView x:Name="tsdTree" DockPanel.Dock="Left" Width="250" Margin="0, 2, 0, 0" ItemsSource="{Binding Path=StructureView}" BorderThickness="0">
<TreeView.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding VisibleChildren}" DataType="{x:Type st:StructureTreeItem}">
(...)
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding VisibleChildren}" DataType="{x:Type st:StructureTreeFolder}">
(...)
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>