/// <summary> /// nodeContainer의 자신과 자손 TreeNode를 폭 우선 탐색 방식으로 열거합니다. /// </summary> /// <param name="nodeContainer"></param> /// <returns></returns> public static IEnumerable <RadTreeNode> GetNodesByBreadthFirst(this IRadTreeNodeContainer nodeContainer) { if (nodeContainer == null) { yield break; } if (IsDebugEnabled) { log.Debug(@"특정 NodeContainer를 폭 우선 탐색을 수행합니다. nodeContainer=[{0}]", nodeContainer.AsTextAndValue()); } // CollectionExtensions.GraphBreadthFirstScan() 을 사용할 수 있지만, TreeView의 RootNode가 여러 개라면, 폭 우선 탐색이 되지 않는다. // 그래서 여기서 전체를 다 구현했다. var toScan = new Queue <RadTreeNode>(GetRootNodesOrSelfNode(nodeContainer)); var scanned = new HashSet <RadTreeNode>(); while (toScan.Count > 0) { RadTreeNode current = toScan.Dequeue(); yield return(current); scanned.Add(current); foreach (RadTreeNode item in current.Nodes.Cast <RadTreeNode>()) { if (scanned.Contains(item) == false) { toScan.Enqueue(item); } } } }
/// <summary> /// 특정 NodeContainer가 TreeView라면 자식 Nodes들을 열거하고, TreeNode라면, TreeNode가 속한 TreeView의 Root Nodes 들을 반환합니다. /// </summary> /// <param name="nodeContainer"></param> /// <returns></returns> public static IEnumerable <RadTreeNode> FindRootNodes(this IRadTreeNodeContainer nodeContainer) { if (IsDebugEnabled) { log.Debug("특정 NodeContainer가 TreeView라면 자식 Nodes들을 열거하고, TreeNode라면, TreeNode가 속한 TreeView의 Root Nodes 들을 반환합니다... " + "nodeContainer=[{0}]", nodeContainer.AsTextAndValue()); } RadTreeView radTreeView = null; if (nodeContainer is RadTreeView) { radTreeView = (RadTreeView)nodeContainer; } else if (nodeContainer is RadTreeNode) { radTreeView = ((RadTreeNode)nodeContainer).TreeView; } if (radTreeView != null) { return(radTreeView.Nodes.Cast <RadTreeNode>()); } return(Enumerable.Empty <RadTreeNode>()); }
/// <summary> /// Depth-First 탐색으로 특정 Node 와 그 자손 Node 들 중에 검사를 통과하는 Node들을 열거합니다. /// </summary> /// <param name="nodeContainer"></param> /// <param name="predicate"></param> /// <returns></returns> public static IEnumerable <RadTreeNode> FindNodes(this IRadTreeNodeContainer nodeContainer, Func <RadTreeNode, bool> predicate) { nodeContainer.ShouldNotBeNull("nodeContainer"); predicate.ShouldNotBeNull("predicate"); if (IsDebugEnabled) { log.Debug("특정 NodeContainer(TreeView or TreeNode)부터 predicate를 만족하는 RadTreeNode 들을 모두 열거합니다. nodeContainer=[{0}]", nodeContainer.AsTextAndValue()); } return(nodeContainer.GetDescendentNodes().Where(predicate)); }
/// <summary> /// nodeContainer의 자신과 자손 TreeNode를 깊이 우선 탐색 방식으로 열거합니다. /// </summary> /// <param name="nodeContainer">기준 노드 또는 TreeView</param> /// <returns></returns> public static IEnumerable <RadTreeNode> GetNodesByDepthFirst(this IRadTreeNodeContainer nodeContainer) { if (nodeContainer == null) { yield break; } if (IsDebugEnabled) { log.Debug(@"특정 NodeContainer를 깊이 우선 탐색을 수행합니다. nodeContainer=[{0}]", nodeContainer.AsTextAndValue()); } foreach (RadTreeNode root in GetRootNodesOrSelfNode(nodeContainer)) { yield return(root); foreach (var node in root.GraphDepthFirstScan(n => n.Nodes.Cast <RadTreeNode>())) { yield return(node); } } }
/// <summary> /// 깊이 우선 탐색을 통해, 현재 Node와 Node의 자손 Node들을 열거합니다. 열거 순서에 상관없으려면 node.GetAllNodes()를 사용하세요 /// </summary> /// <param name="nodeContainer"></param> /// <returns></returns> public static IEnumerable <RadTreeNode> GetDescendentNodes(this IRadTreeNodeContainer nodeContainer) { if (nodeContainer == null) { yield break; } if (IsDebugEnabled) { log.Debug(@"특정 nodeContainer의 자신과 모든 자손 노드들을 열거합니다... nodeContainer=[{0}]", nodeContainer.AsTextAndValue()); } foreach (RadTreeNode rootNode in GetRootNodesOrSelfNode(nodeContainer)) { foreach (var childNode in rootNode.GraphDepthFirstScan(n => n.Nodes.Cast <RadTreeNode>())) { yield return(childNode); } } }
/// <summary> /// 특정 NodeContainer의 자손 중 자식 노드가 없는 TreeNode들 (나무 잎) 을 열거합니다. /// </summary> /// <param name="nodeContainer"></param> /// <returns></returns> public static IEnumerable <RadTreeNode> FindLeafNodes(this IRadTreeNodeContainer nodeContainer) { nodeContainer.ShouldNotBeNull("nodeContainer"); if (IsDebugEnabled) { log.Debug(@"특정 NodeContainer 하위의 모든 Leaf Node (자식이 없는 노드) 들을 Depth First 방식으로 찾습니다. nodeContainer=[{0}]", nodeContainer.AsTextAndValue()); } return(nodeContainer.GetDescendentNodes().Where(n => n.Nodes.Count == 0)); }
/// <summary> /// 지정한 Node Container가 TreeView라면 Nodes 들을 열거하고, TreeNode라면 자신을 반환한다. /// </summary> /// <param name="nodeContainer"></param> /// <returns></returns> public static IEnumerable <RadTreeNode> GetRootNodesOrSelfNode(this IRadTreeNodeContainer nodeContainer) { if (IsDebugEnabled) { log.Debug(@"지정한 Node Container가 TreeView라면 Nodes 들을 열거하고, TreeNode라면 자신을 반환한다. nodeContainer=[{0}]", nodeContainer.AsTextAndValue()); } if (nodeContainer == null) { yield break; } if (nodeContainer is RadTreeNode) { yield return((RadTreeNode)nodeContainer); } else if (nodeContainer is RadTreeView) { var rootNodes = ((RadTreeView)nodeContainer).Nodes; foreach (RadTreeNode node in rootNodes) { yield return(node); } } }