C#中如何基于SQLite数据创建父子嵌套列表绑定TreeView
实现方案
无需递归,通过字典做ID映射仅需两次遍历扁平数据,即可完成任意深度的嵌套结构构建,时间复杂度O(n),不存在递归栈溢出问题。
完整处理代码
// 从数据库读取全量扁平结构科目数据 var subjectnames = await db.SubjectNames.ToListAsync(); var list = new ObservableCollection<ExplorerItem>(); // 第一步:将所有数据库记录转换为ExplorerItem,存入字典以SubjectId为键实现O(1)查找 var itemDic = new Dictionary<long, ExplorerItem>(); foreach (var dbItem in subjectnames) { var uiItem = new ExplorerItem { Name = dbItem.Name, Type = ExplorerItem.ExplorerItemType.Folder, IsExpanded = false }; itemDic.TryAdd(dbItem.SubjectId, uiItem); } // 第二步:遍历建立父子关联 foreach (var dbItem in subjectnames) { var currentUiItem = itemDic[dbItem.SubjectId]; // 能找到对应ParentId的项就挂载到父节点Children下,否则作为根节点加入根集合 if (itemDic.TryGetValue(dbItem.ParentId, out var parentUiItem)) { currentUiItem.Parent = parentUiItem; parentUiItem.Children.Add(currentUiItem); parentUiItem.Type = ExplorerItem.ExplorerItemType.Folder; } else { list.Add(currentUiItem); } } // 可选:修正叶子节点的类型(无Children的节点设为CheckMark/File) foreach (var item in itemDic.Values) { if (item.Children.Count == 0) { item.Type = ExplorerItem.ExplorerItemType.CheckMark; } }
注意事项
- 如果你的根节点ParentId有特殊取值规则(比如为null、等于自身SubjectId),只需要调整根节点判断逻辑即可,其余逻辑不用改动。
- 你定义的
Children属性已经实现懒加载初始化,无需手动为每个节点新建ObservableCollection实例。 - TreeView绑定使用
HierarchicalDataTemplate关联子项集合即可正常展示多层嵌套结构,参考XAML配置:
<TreeView ItemsSource="{Binding YourRootListProperty}"> <TreeView.Resources> <HierarchicalDataTemplate DataType="{x:Type local:ExplorerItem}" ItemsSource="{Binding Children}"> <StackPanel Orientation="Horizontal"> <!-- 可根据Type属性绑定不同图标 --> <TextBlock Text="{Binding Name}" Margin="4,0"/> </StackPanel> </HierarchicalDataTemplate> </TreeView.Resources> </TreeView>
内容的提问来源于stack exchange,提问作者user16474396
相关产品推荐
相关产品推荐

