/// <summary> /// Creates a line which joins the parent NodeControl to the join line /// </summary> private void AddParentToChildLine(double left, double top, FrameworkElement control, HierarchyNode node) { double center = left + (control.Width / 2); double lineTop = top + control.Height; AddLine(center, center, lineTop, lineTop + (LevelSpacing / 2), node); }
/// <summary> /// Recursive method which adds the HierarchyNode controls and lines used to create the tree /// </summary> /// <param name="top">Top margin of the NodeControl</param> /// <param name="left">Left margin of the NodeControl</param> /// <param name="node">Node used to reference the NodeControl and children to display</param> /// <param name="nodeHasParents">used to notify method that the node has no parents</param> /// <returns></returns> private double AddControl(double top, double left, HierarchyNode node, bool nodeHasParents) { double controlLeft = left; FrameworkElement nodeControl = node.Control; //Determine the placement and display all children first if (node.Children.Count > 0) { double lineTop = top + nodeControl.Height + (LevelSpacing / 2); double childTop = top + nodeControl.Height + LevelSpacing; double childLeft = left; //Add child controls to canvas first foreach(HierarchyNode child in node.Children) childLeft = AddControl(childTop, childLeft, child, true); //Create horizontal join line to visually join children to parent double firstNodePoint = node.Children.First().Control.Margin.Left + (node.Children.First().Control.Width / 2); double lastNodePoint = node.Children.Last().Control.Margin.Left + (node.Children.Last().Control.Width / 2); AddLine(firstNodePoint, lastNodePoint, lineTop, lineTop, node); //Find center of join line to create parent line double centerPoint = firstNodePoint + ((lastNodePoint - firstNodePoint) / 2); controlLeft = centerPoint - (nodeControl.Width / 2); left = childLeft + ChildSpacing; } else { //Node has no children so no need to recalculate left position of NodeControl left += nodeControl.Width + ChildSpacing; } //Visually join node to parent if (nodeHasParents) AddChildToParentLine(controlLeft, top, nodeControl, node); //Visually join node to children if (node.Children.Count > 0) AddParentToChildLine(controlLeft, top, nodeControl, node); //Finally add NodeControl to canvas nodeControl.Margin = new Thickness(controlLeft, top, 0, 0); LayoutRoot.Children.Add(node.Control); if (double.IsNaN(LayoutRoot.Height) || LayoutRoot.Height < top + nodeControl.Height + 10) LayoutRoot.Height = top + nodeControl.Height + ChildSpacing; return left; }
/// <summary> /// Refactored method used to display lines in the tree /// </summary> private void AddLine(double x1, double x2, double y1, double y2, HierarchyNode node) { Line newLine = new Line(); newLine.X1 = x1; newLine.X2 = x2; newLine.Y1 = y1; newLine.Y2 = y2; newLine.Stroke = this.lineBrush; newLine.Tag = node; LayoutRoot.Children.Add(newLine); }
/// <summary> /// Creates a line which joins the child NodeControl to the join line /// </summary> private void AddChildToParentLine(double left, double top, FrameworkElement control, HierarchyNode node) { double center = left + (control.Width / 2); AddLine(center, center, top - (LevelSpacing / 2), top, node); }