DevExpress TreeList隐藏无GLAccount子节点的递归算法问题
DevExpress TreeList 节点递归隐藏问题解决方案(VB.NET)
问题核心
需要实现:勾选框触发后,隐藏所有不包含任何Type为"GLAccount"子节点的节点;若兄弟节点存在GLAccount类型节点,其父节点无需隐藏。当前代码仅能处理GLAccount的直接父节点,无法向上递归处理祖辈节点。
现有代码问题
原递归逻辑是从根到叶子遍历,仅处理叶子节点,没有回溯判断父节点是否满足隐藏条件,导致祖辈节点无法根据子节点的最终状态来决定是否隐藏。
修正后的实现代码
保留原勾选框事件逻辑,重写递归处理方法:
Private Sub BarCheckItem1_CheckedChanged_2(sender As Object, e As ItemClickEventArgs) Handles bciHideEmptyAccounts.CheckedChanged If CType(bciHideEmptyAccounts.Checked, Boolean) Then hideNodesRecursive(treeListLeft.Nodes, False) Else hideNodesRecursive(treeListLeft.Nodes, True) End Sub End Sub Private Sub hideNodesRecursive(ByVal nodes As TreeListNodes, ByVal bRestoreVisible As Boolean) For Each node As TreeListNode In nodes ' 先递归处理所有子节点,确保子节点状态先确定 If node.HasChildren Then hideNodesRecursive(node.Nodes, bRestoreVisible) End If If bRestoreVisible Then ' 恢复所有节点可见 node.Visible = True Else ' 判断是否需要隐藏当前节点 Dim hasValidChild As Boolean = False ' 检查子节点中是否有可见的节点(子节点保留可见则说明其下有GLAccount) For Each childNode As TreeListNode In node.Nodes If childNode.Visible Then hasValidChild = True Exit For End If Next ' 当前节点本身是GLAccount,或者有有效子节点,则保持可见 Dim isGLAccount As Boolean = CType(node.GetValue("Type"), String) = "GLAccount" node.Visible = isGLAccount OrElse hasValidChild End If Next End Sub
逻辑说明
- 递归顺序调整:先处理所有子节点,再判断当前节点状态,实现回溯式判断,确保父节点能基于子节点的最终状态做决策。
- 恢复可见逻辑:取消勾选时,直接将所有节点设为可见,快速恢复初始状态。
- 隐藏判断逻辑:
- 检查当前节点的所有子节点,只要有一个子节点可见,说明该子节点下存在GLAccount,当前节点无需隐藏。
- 若当前节点本身是GLAccount类型,无论子节点状态如何都保持可见。
- 既不是GLAccount,又没有有效子节点的节点,设为隐藏。
用例验证
- 用例1:非GLAccount的叶子节点会被正确隐藏,原逻辑的正确行为得以保留。
- 用例2:橙色节点的子节点已全部被隐藏,且其本身不是GLAccount,会被正确隐藏,符合预期规则。
内容的提问来源于stack exchange,提问作者smartini
相关产品推荐
相关产品推荐

