private void SelectAllFromStart(TreeNodeAdv node) { Tree.ClearSelection(); int a = node.Row; int b = Tree.SelectionStart.Row; for (int i = Math.Min(a, b); i <= Math.Max(a, b); i++) { if (Tree.SelectionMode == TreeSelectionMode.Multi || Tree.RowMap[i].Parent == node.Parent) Tree.RowMap[i].IsSelected = true; } }
public void DrawNode(TreeNodeAdv node, DrawContext context) { foreach (NodeControlInfo item in GetNodeControls(node)) { if (item.Bounds.X >= OffsetX && item.Bounds.X - OffsetX < this.Bounds.Width)// skip invisible nodes { context.Bounds = item.Bounds; context.Graphics.SetClip(context.Bounds); item.Control.Draw(node, context); context.Graphics.ResetClip(); } } }
protected override void FocusRow(TreeNodeAdv node) { Tree.SuspendSelectionEvent = true; try { if (Tree.SelectionMode == TreeSelectionMode.Single || Tree.SelectionStart == null) base.FocusRow(node); else if (CanSelect(node)) { SelectAllFromStart(node); Tree.CurrentNode = node; Tree.ScrollTo(node); } } finally { Tree.SuspendSelectionEvent = false; } }
private void AddNode(TreeNodeAdv parent, int index, TreeNodeAdv node) { if (index >= 0 && index < parent.Nodes.Count) parent.Nodes.Insert(index, node); else parent.Nodes.Add(node); node.IsLeaf = Model.IsLeaf(GetPath(node)); if (node.IsLeaf) node.Nodes.Clear(); if (!LoadOnDemand || node.IsExpandedOnce) ReadChilds(node); }
private void ClearNodesSize(TreeModelEventArgs e, TreeNodeAdv parent) { if (e.Indices != null) { foreach (int index in e.Indices) { if (index >= 0 && index < parent.Nodes.Count) { TreeNodeAdv node = parent.Nodes[index]; node.Height = node.RightBounds = null; } else throw new ArgumentOutOfRangeException("Index out of range"); } } else { foreach (TreeNodeAdv node in parent.Nodes) { foreach (object obj in e.Children) if (node.Tag == obj) { node.Height = node.RightBounds = null; } } } }
private void DrawLines(Graphics gr, TreeNodeAdv node, Rectangle rowRect) { if (UseColumns && Columns.Count > 0) gr.SetClip(new Rectangle(0, rowRect.Y, Columns[0].Width, rowRect.Bottom)); TreeNodeAdv curNode = node; while (curNode != _root && curNode != null) { int level = curNode.Level; int x = (level - 1) * _indent + NodePlusMinus.ImageSize / 2 + LeftMargin; int width = NodePlusMinus.Width - NodePlusMinus.ImageSize / 2; int y = rowRect.Y; int y2 = y + rowRect.Height; if (curNode == node) { int midy = y + rowRect.Height / 2; gr.DrawLine(_linePen, x, midy, x + width, midy); if (curNode.NextNode == null) y2 = y + rowRect.Height / 2; } if (node.Row == 0) y = rowRect.Height / 2; if (curNode.NextNode != null || curNode == node) gr.DrawLine(_linePen, x, y, x, y2); curNode = curNode.Parent; } gr.ResetClip(); }
/// <summary> /// Make node visible, scroll if needed. All parent nodes of the specified node must be expanded /// </summary> /// <param name="node"></param> public void ScrollTo(TreeNodeAdv node) { if (node == null) throw new ArgumentNullException("node"); if (!IsMyNode(node)) throw new ArgumentException(); if (node.Row < 0) CreateRowMap(); int row = -1; if (node.Row < FirstVisibleRow) row = node.Row; else { int pageStart = _rowLayout.GetRowBounds(FirstVisibleRow).Top; int rowBottom = _rowLayout.GetRowBounds(node.Row).Bottom; if (rowBottom > pageStart + DisplayRectangle.Height - ColumnHeaderHeight) row = _rowLayout.GetFirstRow(node.Row); } if (row >= _vScrollBar.Minimum && row <= _vScrollBar.Maximum) _vScrollBar.Value = row; }
private int GetNodeWidth(TreeNodeAdv node) { if (node.RightBounds == null) { Rectangle res = GetNodeBounds(GetNodeControls(node, Rectangle.Empty)); node.RightBounds = res.Right; } return node.RightBounds.Value; }
private void OnExpanding(TreeNodeAdv node) { if (Expanding != null) Expanding(this, new TreeViewAdvEventArgs(node)); }
internal void ReadChilds(TreeNodeAdv parentNode, bool performFullUpdate) { if (!parentNode.IsLeaf) { parentNode.IsExpandedOnce = true; List<TreeNodeAdv> oldNodes = new List<TreeNodeAdv>(parentNode.Nodes); parentNode.Nodes.Clear(); if (Model != null) { IEnumerable items = Model.GetChildren(GetPath(parentNode)); if (items != null) foreach (object obj in items) { bool found = false; if (obj != null) { for (int i = 0; i < oldNodes.Count; i++) if (obj == oldNodes[i].Tag) { oldNodes[i].RightBounds = oldNodes[i].Height = null; AddNode(parentNode, -1, oldNodes[i]); oldNodes.RemoveAt(i); found = true; break; } } if (!found) AddNewNode(parentNode, obj, -1); if (performFullUpdate) FullUpdate(); } } } }
private TreeNodeAdv FindNodeByTag(TreeNodeAdv root, object tag) { foreach (TreeNodeAdv node in root.Nodes) { if (node.Tag == tag) return node; TreeNodeAdv res = FindNodeByTag(node, tag); if (res != null) return res; } return null; }
internal bool IsMyNode(TreeNodeAdv node) { if (node == null) return false; if (node.Tree != this) return false; while (node.Parent != null) node = node.Parent; return node == _root; }
internal void ReadChilds(TreeNodeAdv parentNode) { ReadChilds(parentNode, false); }
internal IEnumerable<NodeControlInfo> GetNodeControls(TreeNodeAdv node, Rectangle rowRect) { if (node == null) yield break; int y = rowRect.Y; int x = (node.Level - 1) * _indent + LeftMargin; int width = 0; Rectangle rect = Rectangle.Empty; if (ShowPlusMinus) { width = _plusMinus.GetActualSize(node, _measureContext).Width; rect = new Rectangle(x, y, width, rowRect.Height); if (UseColumns && Columns.Count > 0 && Columns[0].Width < rect.Right) rect.Width = Columns[0].Width - x; yield return new NodeControlInfo(_plusMinus, rect, node); x += width; } if (!UseColumns) { foreach (NodeControl c in NodeControls) { Size s = c.GetActualSize(node, _measureContext); if (!s.IsEmpty) { width = s.Width; rect = new Rectangle(x, y, width, rowRect.Height); x += rect.Width; yield return new NodeControlInfo(c, rect, node); } } } else { int right = 0; foreach (TreeColumn col in Columns) { if (col.IsVisible && col.Width > 0) { right += col.Width; for (int i = 0; i < NodeControls.Count; i++) { NodeControl nc = NodeControls[i]; if (nc.ParentColumn == col) { Size s = nc.GetActualSize(node, _measureContext); if (!s.IsEmpty) { bool isLastControl = true; for (int k = i + 1; k < NodeControls.Count; k++) if (NodeControls[k].ParentColumn == col) { isLastControl = false; break; } width = right - x; if (!isLastControl) width = s.Width; int maxWidth = Math.Max(0, right - x); rect = new Rectangle(x, y, Math.Min(maxWidth, width), rowRect.Height); x += width; yield return new NodeControlInfo(nc, rect, node); } } } x = right; } } } }
internal IEnumerable<NodeControlInfo> GetNodeControls(TreeNodeAdv node) { if (node == null) yield break; Rectangle rowRect = _rowLayout.GetRowBounds(node.Row); foreach (NodeControlInfo n in GetNodeControls(node, rowRect)) yield return n; }
internal Rectangle GetNodeBounds(TreeNodeAdv node) { return GetNodeBounds(GetNodeControls(node)); }
private void CreateNodes() { Selection.Clear(); SelectionStart = null; _root = new TreeNodeAdv(this, null); _root.IsExpanded = true; if (_root.Nodes.Count > 0) CurrentNode = _root.Nodes[0]; else CurrentNode = null; }
internal void SetIsExpanded(TreeNodeAdv node, bool value, bool ignoreChildren) { ExpandArgs eargs = new ExpandArgs(); eargs.Node = node; eargs.Value = value; eargs.IgnoreChildren = ignoreChildren; if (AsyncExpanding && LoadOnDemand && !_threadPool.IsMyThread(Thread.CurrentThread)) { WaitCallback wc = delegate(object argument) { SetIsExpanded((ExpandArgs)argument); }; _threadPool.QueueUserWorkItem(wc, eargs); } else SetIsExpanded(eargs); }
private TreeNodeAdv FindNode(TreeNodeAdv root, TreePath path, int level, bool readChilds) { if (!root.IsExpandedOnce && readChilds) ReadChilds(root); for (int i = 0; i < root.Nodes.Count; i++) { TreeNodeAdv node = root.Nodes[i]; if (node.Tag == path.FullPath[level]) { if (level == path.FullPath.Length - 1) return node; else return FindNode(node, path, level + 1, readChilds); } } return null; }
internal void SetIsExpanded(TreeNodeAdv node, bool value) { if (Root == node && !value) return; //Can't collapse root node if (value) OnExpanding(node); else OnCollapsing(node); if (value && !node.IsExpandedOnce) { if (AsyncExpanding && LoadOnDemand) { AddExpandingNode(node); node.AssignIsExpanded(true); Invalidate(); } ReadChilds(node, AsyncExpanding); RemoveExpandingNode(node); } node.AssignIsExpanded(value); SmartFullUpdate(); if (value) OnExpanded(node); else OnCollapsed(node); }
private NodeControlInfo GetNodeControlInfoAt(TreeNodeAdv node, Point point) { Rectangle rect = _rowLayout.GetRowBounds(FirstVisibleRow); point.Y += (rect.Y - ColumnHeaderHeight); point.X += OffsetX; foreach (NodeControlInfo info in GetNodeControls(node)) if (info.Bounds.Contains(point)) return info; if (FullRowSelect) return new NodeControlInfo(null, Rectangle.Empty, node); else return NodeControlInfo.Empty; }
internal void SetIsExpandedRecursive(TreeNodeAdv root, bool value) { for (int i = 0; i < root.Nodes.Count; i++) { TreeNodeAdv node = root.Nodes[i]; node.IsExpanded = value; SetIsExpandedRecursive(node, value); } }
private void OnCollapsing(TreeNodeAdv node) { if (Collapsing != null) Collapsing(this, new TreeViewAdvEventArgs(node)); }
protected bool CanSelect(TreeNodeAdv node) { if (Tree.SelectionMode == TreeSelectionMode.MultiSameParent) { return (Tree.SelectionStart == null || node.Parent == Tree.SelectionStart.Parent); } else return true; }
private void RemoveExpandingNode(TreeNodeAdv node) { node.IsExpandingNow = false; _expandingNodes.Remove(node); }
/// <summary> /// Expand all parent nodes, andd scroll to the specified node /// </summary> public void EnsureVisible(TreeNodeAdv node) { if (node == null) throw new ArgumentNullException("node"); if (!IsMyNode(node)) throw new ArgumentException(); TreeNodeAdv parent = node.Parent; while (parent != _root) { parent.IsExpanded = true; parent = parent.Parent; } ScrollTo(node); }
private void AddExpandingNode(TreeNodeAdv node) { node.IsExpandingNow = true; _expandingNodes.Add(node); ExpandingIcon.Start(); }
public TreePath GetPath(TreeNodeAdv node) { if (node == _root) return TreePath.Empty; else { Stack<object> stack = new Stack<object>(); while (node != _root && node != null) { stack.Push(node.Tag); node = node.Parent; } return new TreePath(stack.ToArray()); } }
protected virtual void FocusRow(TreeNodeAdv node) { Tree.SuspendSelectionEvent = true; try { Tree.ClearSelection(); Tree.CurrentNode = node; Tree.SelectionStart = node; node.IsSelected = true; Tree.ScrollTo(node); } finally { Tree.SuspendSelectionEvent = false; } }
private void AddNewNode(TreeNodeAdv parent, object tag, int index) { TreeNodeAdv node = new TreeNodeAdv(this, tag); AddNode(parent, index, node); }