private void FillOurTreeView() { #region Old way //TreeViewNode t1 = new TreeViewNode("test1"); //treeViewControl1.Root.Children.Add(t1); //TreeViewNode t11 = new TreeViewNode("subtest11"); //t1.VMembers.Children.Add(t11); //TreeViewNode t12 = new TreeViewNode("subtest12"); //t1.VMembers.Children.Add(t12); //TreeViewNode t2 = new TreeViewNode("test2"); //treeViewControl1.Root.Children.Add(t2); //t2.MyNodeControl.TreeLineStyle = RedLineStyle; //TreeViewNode t21 = new TreeViewNode("subtest21"); //t2.VMembers.Children.Add(t21); //TreeViewNode t22 = new TreeViewNode("subtest22"); //t2.VMembers.Children.Add(t22); ////t21.VMembers.Children.Add(new SampleRootBlock()); //TreeViewNode t211 = new TreeViewNode("subtest211"); //t21.VMembers.Children.Add(t211); //// t21.HMembers.Children.Add(new ButtonBlock("Hello")); #endregion #region New way TreeViewNode t1 = treeViewControl1.AddNode("test1"); TreeViewNode t11 = t1.AddNode("subtest11"); TreeViewNode t12 = t1.AddNode("subtest12"); TreeViewNode t2 = treeViewControl1.AddNode("test2"); TreeViewNode t21 = t2.AddNode("subtest21"); TreeViewNode t211 = t21.AddNode("subtest211"); TreeViewNode t22 = t2.AddNode("subtest22"); #endregion NodeRelationship r = new NodeRelationship(); r.Sender = t11; r.Receivers = new List <Block>(); r.Receivers.Add(t22); r.Receivers.Add(t21); treeViewControl1.Root.Relationship = r; }
private static bool IsAllowedToHaveRelationDefault(TreeNode parent, TreeNode child, NodeRelationship relation) { return true; }
private void PaintDragDestinationGraphics(NodeRelationship _prevDNL = NodeRelationship.Null, TreeNode _prevDN = null) { if ((_prevDN == null || _prevDNL == NodeRelationship.Null) && (_dropNode == null || _dropNodeLocation == NodeRelationship.Null)) return; Color DrawColor; Color SelectColor; TreeNode node; NodeRelationship location; bool removal; if (_prevDN != null & _prevDNL != NodeRelationship.Null) { DrawColor = SystemColors.Window; SelectColor = SystemColors.Window; node = _prevDN; location = _prevDNL; removal = true; } else { DrawColor = SystemColors.WindowText; SelectColor = SystemColors.MenuHighlight; node = _dropNode; location = _dropNodeLocation; removal=false; } Graphics g = CreateGraphics(); int dropNodeImageWidth = ImageList.Images[node.ImageIndex == -1 ? 0 : node.ImageIndex].Size.Width + 2; // Once again, we are not dragging to node over, draw the placeholder using the ParentDragDrop bounds int LeftPos, RightPos, VertPos = 0; LeftPos = node.Bounds.Left - dropNodeImageWidth; RightPos = Width; switch (location) { case NodeRelationship.ChildGoesAbove: VertPos = node.Bounds.Top; break; case NodeRelationship.ChildGoesInside: VertPos = node.Bounds.Bottom - node.Bounds.Height / 2; LeftPos = node.Bounds.Right + 6; if (removal) { using (Brush brush = new System.Drawing.SolidBrush(SelectColor)) g.FillRectangle(brush, new Rectangle(node.Bounds.Location, node.Bounds.Size)); if (node.TreeView != null) OnDrawNode(new DrawTreeNodeEventArgs(g, node, Helper.MakeDrawNodeRectangle(node.Bounds), TreeNodeStates.Default)); } else { using (Brush brush = new System.Drawing.SolidBrush(Color.FromArgb(64, SelectColor))) g.FillRectangle(brush, new Rectangle(node.Bounds.Location, node.Bounds.Size)); } using (Pen pen = new System.Drawing.Pen(DrawColor, 1)) g.DrawRectangle(pen, new Rectangle(node.Bounds.Location, node.Bounds.Size)); Point[] triangle = new Point[4] { new Point(LeftPos, VertPos-1), new Point(LeftPos, VertPos), new Point(LeftPos + 11, VertPos + 4), new Point(LeftPos + 11, VertPos - 5) }; using (Brush brush = new System.Drawing.SolidBrush(DrawColor)) g.FillPolygon(brush, triangle); break; case NodeRelationship.ChildGoesUnder: VertPos = node.Bounds.Bottom; break; } using (Pen pen = new System.Drawing.Pen(DrawColor, 2)) g.DrawLine(pen, new Point(LeftPos, VertPos), new Point(RightPos, VertPos)); }
public void MoveNode(TreeNode what, TreeNode where, NodeRelationship relation, NodeRelationship subRelation = NodeRelationship.Null, bool suspendUpdate = false) { if (!IsAllowedToHaveRelation(where,what,relation)) return; if (subRelation == NodeRelationship.Null) subRelation = Settings.Current.DragIntoFolderToLastPosition ? NodeRelationship.ChildGoesUnder : NodeRelationship.ChildGoesAbove; TreeNode result = null; if (!suspendUpdate) BeginUpdate(); if (where == null) { what.Remove(); Nodes.Add(what); } else { if (what != where) switch (relation) { case NodeRelationship.ChildGoesAbove: what.Remove(); if (where.Parent != null) where.Parent.Nodes.Insert(where.Index, what); else Nodes.Insert(where.Index, what); result = what; break; case NodeRelationship.ChildGoesInside: what.Remove(); if (subRelation == NodeRelationship.ChildGoesUnder) where.Nodes.Add(what); if (subRelation == NodeRelationship.ChildGoesAbove) where.Nodes.Insert(0, what); result = what; break; case NodeRelationship.ChildGoesUnder: what.Remove(); if (where.Parent != null) where.Parent.Nodes.Insert(where.Index + 1, what); else Nodes.Insert(where.Index + 1, what); result = what; break; } } if (result!=null) SelectedNode = result; if (!suspendUpdate) EndUpdate(); OnNodeMoved(result, suspendUpdate); }
protected override void OnDragOver(DragEventArgs drgevent) { if (!DraggingInProgress) { drgevent.Effect = DragDropEffects.None; return; } drgevent.Effect = DragDropEffects.Move; TreeNode prevDN = _dropNode; NodeRelationship prevDNL = _dropNodeLocation; // Get actual drop node _dropNode = GetNodeAt(PointToClient(new Point(drgevent.X, drgevent.Y))); if (_dropNode != null) { int OffsetY = PointToClient(Cursor.Position).Y - _dropNode.Bounds.Top; if (IsFolder(_dropNode)) { if (OffsetY < (_dropNode.Bounds.Height / 3)) _dropNodeLocation = NodeRelationship.ChildGoesAbove; else if (OffsetY > (_dropNode.Bounds.Height * 2 / 3)) _dropNodeLocation = NodeRelationship.ChildGoesUnder; else _dropNodeLocation = NodeRelationship.ChildGoesInside; } else { if (OffsetY < (_dropNode.Bounds.Height / 2)) _dropNodeLocation = NodeRelationship.ChildGoesAbove; else _dropNodeLocation = NodeRelationship.ChildGoesUnder; } //Check if we are allowed to put this into that if (!IsAllowedToHaveRelation(_dropNode, _dragNode, _dropNodeLocation)) { drgevent.Effect = DragDropEffects.None; _dropNodeLocation = NodeRelationship.Null; } if (_dropNode == _dragNode && _dropNodeLocation == NodeRelationship.ChildGoesInside) { drgevent.Effect = DragDropEffects.None; _dropNodeLocation = NodeRelationship.Null; } // Avoid that drop node is child of drag node TreeNode tmpNode = _dropNode; while (tmpNode.Parent != null) { if (tmpNode.Parent == this._dragNode) { drgevent.Effect = DragDropEffects.None; _dropNodeLocation = NodeRelationship.Null; } tmpNode = tmpNode.Parent; } } //Mechanism to scroll when reaching the end if (_dropNode != null) { //Always ensure that the node we are dropping over/in/under is visible _dropNode.EnsureVisible(); //Highlight previous node if it exists and... if (_dropNode.PrevNode != null) { //If previous node has no nodes or isnt expanded then this node is a single node and should be visible if (_dropNode.PrevNode.Nodes.Count == 0 || !_dropNode.PrevNode.IsExpanded) _dropNode.PrevNode.EnsureVisible(); //If previous node has nodes and is expanded then its last visible child should be made visible else { //Find last visible child recursively TreeNode lastChild = _dropNode.PrevNode.Nodes[_dropNode.PrevNode.Nodes.Count - 1]; while (lastChild.Nodes.Count > 0 && lastChild.IsExpanded) lastChild = lastChild.Nodes[lastChild.Nodes.Count - 1]; lastChild.EnsureVisible(); } } //Highlight parent node if previous node doesnt exist (meaning node above this node is its parent) else { if (_dropNode.Parent != null) _dropNode.Parent.EnsureVisible(); } //Highlight next node if it exists and... if (_dropNode.NextNode != null) { //If this node has no nodes or isnt expanded then it is single, and next node should be visible if (_dropNode.Nodes.Count == 0 || !_dropNode.IsExpanded) _dropNode.NextNode.EnsureVisible(); //If this node has nodes and is expanded then we should select its first child else _dropNode.Nodes[0].EnsureVisible(); } //Highlight next node after parent node if there is no next node else { if (_dropNode.Nodes.Count == 0 || !_dropNode.IsExpanded) if (_dropNode.Parent != null && _dropNode.Parent.NextNode != null) _dropNode.Parent.NextNode.EnsureVisible(); } } if (prevDNL != _dropNodeLocation || prevDN != _dropNode) { PaintDragDestinationGraphics(prevDNL, prevDN); PaintDragDestinationGraphics(); } base.OnDragOver(drgevent); }
/// <summary> /// Get the sum of the branch lengths from this node to the specified node. /// </summary> /// <param name="otherNode">The node that should be reached</param> /// <param name="nodeRelationship">A value indicating how this node is related to <paramref name="otherNode"/>.</param> /// <returns>The sum of the branch lengths from this node to the specified node.</returns> public double PathLengthTo(TreeNode otherNode, NodeRelationship nodeRelationship = NodeRelationship.Unknown) { Contract.Requires(otherNode != null); TreeNode LCA = null; if (this == otherNode) { return(0); } if (nodeRelationship == NodeRelationship.Unknown) { List <TreeNode> myChildren = this.GetChildrenRecursive(); if (myChildren.Contains(otherNode)) { nodeRelationship = NodeRelationship.Ancestor; } else { List <TreeNode> otherChildren = otherNode.GetChildrenRecursive(); if (otherChildren.Contains(this)) { nodeRelationship = NodeRelationship.Descendant; } else { LCA = GetLastCommonAncestor(new TreeNode[] { this, otherNode }); if (LCA != null) { nodeRelationship = NodeRelationship.Relatives; } else { throw new InvalidOperationException("The two nodes do not belong to the same tree!"); } } } } switch (nodeRelationship) { case NodeRelationship.Relatives: return(LCA.PathLengthTo(this, NodeRelationship.Ancestor) + LCA.PathLengthTo(otherNode, NodeRelationship.Ancestor)); case NodeRelationship.Ancestor: for (int i = 0; i < this.Children.Count; i++) { if (this.Children[i] == otherNode) { return(this.Children[i].Length); } else if (this.Children[i].GetChildrenRecursive().Contains(otherNode)) { return(this.Children[i].Length + this.Children[i].PathLengthTo(otherNode, NodeRelationship.Ancestor)); } } throw new InvalidOperationException("Unexpected code path!"); case NodeRelationship.Descendant: return(otherNode.PathLengthTo(this, NodeRelationship.Ancestor)); default: throw new InvalidOperationException("The two nodes do not belong to the same tree!"); } }
private string traverse_tree(XElement node, string parent_id, NodeRelationship relationship) { // get this nodes infko string tagname = node.Name.LocalName; if (tagname == "math") { traverse_tree(node.FirstNode as XElement, parent_id, NodeRelationship.Right); return(""); } string my_id = node.Attribute(ns + "id") == null ? null : (string)(node.Attribute(ns + "id").Value); // relationsip if (my_id != null) { //Console.WriteLine(my_id + " is " + relationship + " of " + parent_id); edge_list.Add(new Tuple <string, NodeRelationship, string>(my_id, relationship, parent_id)); } // handle children switch (tagname) { case "mfrac": traverse_tree(node.FirstNode as XElement, my_id, NodeRelationship.Above); traverse_tree(node.LastNode as XElement, my_id, NodeRelationship.Below); return(my_id); case "mrow": string left_id = traverse_tree(node.FirstNode as XElement, parent_id, relationship); traverse_tree(node.LastNode as XElement, left_id, NodeRelationship.Right); return(left_id); case "msup": string super_base_id = traverse_tree(node.FirstNode as XElement, parent_id, relationship); traverse_tree(node.LastNode as XElement, super_base_id, NodeRelationship.SuperScript); return(super_base_id); case "msub": string sub_base_id = traverse_tree(node.FirstNode as XElement, parent_id, relationship); traverse_tree(node.LastNode as XElement, sub_base_id, NodeRelationship.SubScript); return(sub_base_id); case "msqrt": string first_under = traverse_tree(node.FirstNode as XElement, my_id, NodeRelationship.Under); if (node.LastNode != node.FirstNode) { traverse_tree(node.FirstNode.NextNode as XElement, first_under, NodeRelationship.Right); } return(my_id); case "msubsup": var child = node.FirstNode; string sub_sup_base_id = traverse_tree(child as XElement, parent_id, relationship); traverse_tree(child.NextNode as XElement, sub_sup_base_id, NodeRelationship.Below); traverse_tree(child.NextNode.NextNode as XElement, sub_sup_base_id, NodeRelationship.Above); return(sub_sup_base_id); case "munderover": child = node.FirstNode; string under_over_base_id = traverse_tree(child as XElement, parent_id, relationship); traverse_tree(child.NextNode as XElement, under_over_base_id, NodeRelationship.Below); traverse_tree(child.NextNode.NextNode as XElement, under_over_base_id, NodeRelationship.Above); return(under_over_base_id); case "munder": string top_base_id = traverse_tree(node.FirstNode as XElement, parent_id, relationship); traverse_tree(node.LastNode as XElement, top_base_id, NodeRelationship.Below); return(top_base_id); } // everything esle return(my_id); }
/// <summary> /// In this method we check wether a node can get placed near another node. /// </summary> /// <param name="parent">Node being the receiver</param> /// <param name="child">Node that is trying to get attached</param> /// <example> /// You are not allowed to place Event above Start, so any relation which makes it so will be denied. /// </example> private bool TreeViewNodes_IsAllowedToHaveRelation(TreeNode parent, TreeNode child, NodeRelationship relation) { if (child.Tag == null) throw new ArgumentException("child", "Moving a TreeNode without a Tag, WTF?"); if (parent.Tag == null) throw new ArgumentException("parent", "Moving a TreeNode without a Tag, WTF?"); if (relation == NodeRelationship.ChildGoesInside && !TreeViewNodes.IsFolder(parent)) return false; //Everything except comments cant go above Start (which can only occur in root) //Therefore, for each node that isnt a comment, and is trying to fit on one level with something that is in root... if (relation != NodeRelationship.ChildGoesInside && parent.Parent == null && !(child.Tag.GetType() == typeof(MissionNode_Comment) || child.Tag.GetType() == typeof(MissionNode_Start))) { //Check that we are not inserting directly above Start node... if (relation == NodeRelationship.ChildGoesAbove && parent.Tag.GetType() == typeof(MissionNode_Start)) return false; //...and check that we are not inserting near a node that is above Start node if (TreeViewNodes.Nodes.IndexOf(_startNode) > TreeViewNodes.Nodes.IndexOf(parent)) return false; } //Start, Comment and Unknown cannot go inside anything, start because it must stay on top and other two because they cant have Parent_ID attribute added to them if (child.Tag.GetType() == typeof(MissionNode_Start) || child.Tag.GetType() == typeof(MissionNode_Comment) || child.Tag.GetType() == typeof(MissionNode_Unknown)) { //Refuse to go inside anything... if (relation == NodeRelationship.ChildGoesInside) return false; //...or next to a node that is inside something... if (parent.Parent != null) return false; } //Start additionally cannot go below anything that isnt a comment if (child.Tag.GetType() == typeof(MissionNode_Start)) { //Never go under anything other than a comment or yourself if (relation == NodeRelationship.ChildGoesUnder && parent.Tag.GetType() != typeof(MissionNode_Comment) && parent != child) return false; //Go through nodes until we meet the node we are becoming parented to //If we find anything except comment on the way, this means we are going below for (int i = 0; i < TreeViewNodes.Nodes.Count; i++) { //When we found something other than a comment and the dragged node if (TreeViewNodes.Nodes[i].Tag.GetType() != typeof(MissionNode_Comment) && TreeViewNodes.Nodes[i] != child) //In case this is the node we are inserting above - allow it, otherwise deny it if (relation == NodeRelationship.ChildGoesAbove && TreeViewNodes.Nodes[i] == parent) break; else return false; if (TreeViewNodes.Nodes[i] == parent) break; } } return true; }
/// <summary> /// In this method we check wether a statement can get placed near another statement. /// </summary> /// <param name="parent">Node being the receiver</param> /// <param name="child">Node that is trying to get attached</param> /// <example> /// You are not allowed to place a Condition into Actions root. /// </example> private bool TreeViewStatements_IsAllowedToHaveRelation(TreeNode parent, TreeNode child, NodeRelationship relation) { if (child.Tag == null || parent.Tag == null) // This might be a comment or a folder return false; //You cannot go inside something that isnt a folder if (relation == NodeRelationship.ChildGoesInside && !TreeViewStatements.IsFolder(parent)) return false; //Non-statements cannot move at all if (!(child.Tag is MissionStatement)) return false; //If going inside, Conditions can only go inside codintion folder, actions can go inside actions folder, comment can go anywhere if (relation == NodeRelationship.ChildGoesInside && (((string)parent.Tag == "conditions" && ((MissionStatement)child.Tag).Kind == MissionStatementKind.Action) || ((string)parent.Tag == "actions" && ((MissionStatement)child.Tag).Kind == MissionStatementKind.Condition) || ((string)parent.Tag != "actions" && (string)parent.Tag != "conditions"))) return false; //Comments cannot go inside conditions! if (relation == NodeRelationship.ChildGoesInside && ((string)parent.Tag == "conditions" && ((MissionStatement)child.Tag).Kind == MissionStatementKind.Commentary)) return false; //If going adjacent to something //Conditions can only go adjacent to conditions or comments inside conditions folder //Actions can only go adjacent to actions or comments inside actions folder if (relation == NodeRelationship.ChildGoesAbove || relation == NodeRelationship.ChildGoesUnder) { if (!(parent.Tag is MissionStatement)) return false; if ((((MissionStatement)child.Tag).Kind == MissionStatementKind.Action) && ((string)parent.Parent.Tag != "actions")) return false; if ((((MissionStatement)child.Tag).Kind == MissionStatementKind.Condition) && ((string)parent.Parent.Tag != "conditions")) return false; } //Comments also cannot go under last condition if (relation == NodeRelationship.ChildGoesUnder && (((MissionStatement)child.Tag).Kind == MissionStatementKind.Commentary)) { if (parent.Parent != null && parent.Parent.LastNode == parent && (string)parent.Parent.Tag == "conditions") return false; } return true; }
public Task Sort() { var nodes = this.nodes.ToDictionary ( kvp => kvp.Key, kvp => new NodeRelationship { Dependencies = kvp.Value.Dependencies.ToHashSet(actionComparer), Dependents = kvp.Value.Dependents.ToHashSet(actionComparer) }, actionComparer ); var taskDictionary = this.nodes.ToDictionary ( kvp => kvp.Key, kvp => new TaskRelationship(), actionComparer ); var sortedNodeIds = new List <Node>(); // Add root nodes sortedNodeIds.AddRange(this.nodes.Where(kvp => kvp.Value.Dependencies.Count == 0).Select(kvp => kvp.Key)); var rootTasks = new List <Task>(); foreach (Node nodeId in sortedNodeIds) { var task = new Task(nodeId.Action); taskDictionary[nodeId].Task = task; rootTasks.Add(task); } for (var index = 0; index < sortedNodeIds.Count; ++index) { Node nodeId = sortedNodeIds[index]; Task task = taskDictionary[nodeId].Task ?? Task.WhenAll(taskDictionary[nodeId].TaskDependencies).ContinueWith((Task t) => { nodeId.Action.Invoke(); }); taskDictionary[nodeId].Task = task; HashSet <Node> dependentIds = nodes[nodeId].Dependents; foreach (Node dependentId in dependentIds) { NodeRelationship dependent = nodes[dependentId]; taskDictionary[dependentId].TaskDependencies.Add(task); dependent.Dependencies.Remove(sortedNodeIds[index]); if (dependent.Dependencies.Count == 0) { sortedNodeIds.Add(dependentId); } } } var cycledNodes = nodes.Where(kvp => kvp.Value.Dependencies.Count != 0).ToArray(); if (cycledNodes.Length > 0) { return(Task.Run(() => Console.WriteLine("Failed to run. Cycle detected with the following nodes (" + string.Join(", ", cycledNodes.Select(kvp => kvp.Key.Name)) + ")"))); } else { foreach (Task task in rootTasks) { task.Start(); } return(Task.WhenAll(taskDictionary.Values.Select(x => x.Task)).ContinueWith((Task t) => Console.WriteLine(""))); } }
public void MoveNode(TreeNode what, TreeNode where, NodeRelationship relation, NodeRelationship subRelation = NodeRelationship.Null, bool suspendUpdate = false) { if (!IsAllowedToHaveRelation(where, what, relation)) { return; } if (subRelation == NodeRelationship.Null) { subRelation = Settings.Current.DragIntoFolderToLastPosition ? NodeRelationship.ChildGoesUnder : NodeRelationship.ChildGoesAbove; } TreeNode result = null; if (!suspendUpdate) { BeginUpdate(); } if (where == null) { what.Remove(); Nodes.Add(what); } else { if (what != where) { switch (relation) { case NodeRelationship.ChildGoesAbove: what.Remove(); if (where.Parent != null) { where.Parent.Nodes.Insert(where.Index, what); } else { Nodes.Insert(where.Index, what); } result = what; break; case NodeRelationship.ChildGoesInside: what.Remove(); if (subRelation == NodeRelationship.ChildGoesUnder) { where.Nodes.Add(what); } if (subRelation == NodeRelationship.ChildGoesAbove) { where.Nodes.Insert(0, what); } result = what; break; case NodeRelationship.ChildGoesUnder: what.Remove(); if (where.Parent != null) { where.Parent.Nodes.Insert(where.Index + 1, what); } else { Nodes.Insert(where.Index + 1, what); } result = what; break; } } } if (result != null) { SelectedNode = result; } if (!suspendUpdate) { EndUpdate(); } OnNodeMoved(result, new NodeMovedEventArgs(suspendUpdate)); }
protected override void OnDragOver(DragEventArgs drgevent) { if (!DraggingInProgress) { drgevent.Effect = DragDropEffects.None; return; } drgevent.Effect = DragDropEffects.Move; TreeNode prevDN = _dropNode; NodeRelationship prevDNL = _dropNodeLocation; // Get actual drop node _dropNode = GetNodeAt(PointToClient(new Point(drgevent.X, drgevent.Y))); if (_dropNode != null) { int OffsetY = PointToClient(Cursor.Position).Y - _dropNode.Bounds.Top; if (IsFolder(_dropNode)) { if (OffsetY < (_dropNode.Bounds.Height / 3)) { _dropNodeLocation = NodeRelationship.ChildGoesAbove; } else if (OffsetY > (_dropNode.Bounds.Height * 2 / 3)) { _dropNodeLocation = NodeRelationship.ChildGoesUnder; } else { _dropNodeLocation = NodeRelationship.ChildGoesInside; } } else { if (OffsetY < (_dropNode.Bounds.Height / 2)) { _dropNodeLocation = NodeRelationship.ChildGoesAbove; } else { _dropNodeLocation = NodeRelationship.ChildGoesUnder; } } //Check if we are allowed to put this into that if (!IsAllowedToHaveRelation(_dropNode, _dragNode, _dropNodeLocation)) { drgevent.Effect = DragDropEffects.None; _dropNodeLocation = NodeRelationship.Null; } if (_dropNode == _dragNode && _dropNodeLocation == NodeRelationship.ChildGoesInside) { drgevent.Effect = DragDropEffects.None; _dropNodeLocation = NodeRelationship.Null; } // Avoid that drop node is child of drag node TreeNode tmpNode = _dropNode; while (tmpNode.Parent != null) { if (tmpNode.Parent == this._dragNode) { drgevent.Effect = DragDropEffects.None; _dropNodeLocation = NodeRelationship.Null; } tmpNode = tmpNode.Parent; } } //Mechanism to scroll when reaching the end if (_dropNode != null) { //Always ensure that the node we are dropping over/in/under is visible _dropNode.EnsureVisible(); //Highlight previous node if it exists and... if (_dropNode.PrevNode != null) { //If previous node has no nodes or isn't expanded then this node is a single node and should be visible if (_dropNode.PrevNode.Nodes.Count == 0 || !_dropNode.PrevNode.IsExpanded) { _dropNode.PrevNode.EnsureVisible(); } //If previous node has nodes and is expanded then its last visible child should be made visible else { //Find last visible child recursively TreeNode lastChild = _dropNode.PrevNode.Nodes[_dropNode.PrevNode.Nodes.Count - 1]; while (lastChild.Nodes.Count > 0 && lastChild.IsExpanded) { lastChild = lastChild.Nodes[lastChild.Nodes.Count - 1]; } lastChild.EnsureVisible(); } } //Highlight parent node if previous node doesnt exist (meaning node above this node is its parent) else { if (_dropNode.Parent != null) { _dropNode.Parent.EnsureVisible(); } } //Highlight next node if it exists and... if (_dropNode.NextNode != null) { //If this node has no nodes or isn't expanded then it is single, and next node should be visible if (_dropNode.Nodes.Count == 0 || !_dropNode.IsExpanded) { _dropNode.NextNode.EnsureVisible(); } //If this node has nodes and is expanded then we should select its first child else { _dropNode.Nodes[0].EnsureVisible(); } } //Highlight next node after parent node if there is no next node else { if (_dropNode.Nodes.Count == 0 || !_dropNode.IsExpanded) { if (_dropNode.Parent != null && _dropNode.Parent.NextNode != null) { _dropNode.Parent.NextNode.EnsureVisible(); } } } } if (prevDNL != _dropNodeLocation || prevDN != _dropNode) { PaintDragDestinationGraphics(prevDNL, prevDN); PaintDragDestinationGraphics(); } base.OnDragOver(drgevent); }
private void PaintDragDestinationGraphics(NodeRelationship _prevDNL = NodeRelationship.Null, TreeNode _prevDN = null) { if ((_prevDN == null || _prevDNL == NodeRelationship.Null) && (_dropNode == null || _dropNodeLocation == NodeRelationship.Null)) { return; } Color DrawColor; Color SelectColor; TreeNode node; NodeRelationship location; bool removal; if (_prevDN != null & _prevDNL != NodeRelationship.Null) { DrawColor = SystemColors.Window; SelectColor = SystemColors.Window; node = _prevDN; location = _prevDNL; removal = true; } else { DrawColor = SystemColors.WindowText; SelectColor = SystemColors.MenuHighlight; node = _dropNode; location = _dropNodeLocation; removal = false; } Graphics g = CreateGraphics(); int dropNodeImageWidth = ImageList.Images[node.ImageIndex == -1 ? 0 : node.ImageIndex].Size.Width + 2; // Once again, we are not dragging to node over, draw the placeholder using the ParentDragDrop bounds int LeftPos, RightPos, VertPos = 0; LeftPos = node.Bounds.Left - dropNodeImageWidth; RightPos = Width; switch (location) { case NodeRelationship.ChildGoesAbove: VertPos = node.Bounds.Top; break; case NodeRelationship.ChildGoesInside: VertPos = node.Bounds.Bottom - node.Bounds.Height / 2; LeftPos = node.Bounds.Right + 6; if (removal) { using (Brush brush = new System.Drawing.SolidBrush(SelectColor)) g.FillRectangle(brush, new Rectangle(node.Bounds.Location, node.Bounds.Size)); if (node.TreeView != null) { OnDrawNode(new DrawTreeNodeEventArgs(g, node, Helper.MakeDrawNodeRectangle(node.Bounds), TreeNodeStates.Default)); } } else { using (Brush brush = new System.Drawing.SolidBrush(Color.FromArgb(64, SelectColor))) g.FillRectangle(brush, new Rectangle(node.Bounds.Location, node.Bounds.Size)); } using (Pen pen = new System.Drawing.Pen(DrawColor, 1)) g.DrawRectangle(pen, new Rectangle(node.Bounds.Location, node.Bounds.Size)); Point[] triangle = new Point[4] { new Point(LeftPos, VertPos - 1), new Point(LeftPos, VertPos), new Point(LeftPos + 11, VertPos + 4), new Point(LeftPos + 11, VertPos - 5) }; using (Brush brush = new System.Drawing.SolidBrush(DrawColor)) g.FillPolygon(brush, triangle); break; case NodeRelationship.ChildGoesUnder: VertPos = node.Bounds.Bottom; break; } using (Pen pen = new System.Drawing.Pen(DrawColor, 2)) g.DrawLine(pen, new Point(LeftPos, VertPos), new Point(RightPos, VertPos)); }
private static bool IsAllowedToHaveRelationDefault(TreeNode parent, TreeNode child, NodeRelationship relation) { return(true); }