如何在绑定ItemsSource的嵌套TreeView中实现搜索功能
TreeView搜索功能的问题与解决
问题背景
我有一个通过ItemsSource加载数据的TreeView,加载数据的代码如下:
[ObservableProperty] private ObservableCollection<FileSystemItem> items = new ObservableCollection<FileSystemItem>(); private async Task LoadFolder(string folderPath, ObservableCollection<FileSystemItem> parentCollection) { foreach (string directoryPath in Directory.EnumerateDirectories(folderPath)) { var directoryInfo = new DirectoryInfo(directoryPath); var directoryNode = new FileSystemItem(directoryInfo); await LoadFolder(directoryPath, directoryNode.Children); parentCollection.Add(directoryNode); } foreach (string filePath in Directory.EnumerateFiles(folderPath)) { var fileInfo = new FileInfo(filePath); var fileNode = new FileSystemItem(fileInfo); parentCollection.Add(fileNode); } }
我想给这个TreeView实现搜索功能,当前使用的搜索代码如下:
Items = new(Search(query, _backupItems)); public IEnumerable<FileSystemItem> Search(string query, ObservableCollection<FileSystemItem> nodes) { foreach (var node in nodes) { if (node.DisplayName.Contains(query, StringComparison.OrdinalIgnoreCase)) { yield return node; } foreach (var result in Search(query, node.Children)) { yield return result; } } }
但遇到两个问题:
- 搜索后清空文本框时,ItemTemplateSelector使用了错误的模板;
- 搜索结果全部被添加到TreeView的根层级,希望能保留搜索项的父文件夹层级展示。
更新1
提供示例项目包,需先修改文件夹路径(需创建包含子文件夹及ttf、otf或woff文件的文件夹),代码如下:
await LoadFilesAndFolders(@"D:\Applications\Font");
更新2
我使用了以下代码,目前看起来一切正常:
public void OnAutoSuggestBoxTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args) { var query = sender.Text.ToLower(); // 对主集合应用筛选 advancedCollectionView.Filter = item => { var fileSystemItem = item as FileSystemItem; if (fileSystemItem == null) return false; return FilterItems(fileSystemItem, query); }; // 对主集合中每个项的子项应用筛选 foreach (var item in Items) { ApplyFilterToItem(item, query); } } private void ApplyFilterToItem(FileSystemItem item, string query) { item.MyChildren.Filter = childItem => { var childFileSystemItem = childItem as FileSystemItem; if (childFileSystemItem == null) return false; return FilterItems(childFileSystemItem, query); }; // 递归对每个子项应用筛选 foreach (var child in item.Children) { ApplyFilterToItem(child, query); } } bool FilterItems(FileSystemItem item, string query) { // 检查当前项是否匹配查询条件 if (item.DisplayName.ToLower().Contains(query)) { return true; } // 递归检查子项是否有匹配的 foreach (var child in item.Children) { if (FilterItems(child, query)) { return true; } } return false; }
内容的提问来源于stack exchange,提问作者Chibako
相关产品推荐
相关产品推荐

