// Constructor. public TreeViewExCancelEventArgs (TreeNodeEx node, bool cancel, TreeViewExAction action) : base(cancel) { this.node = node; this.action = action; }
internal int AddSorted(TreeNodeEx node) { int pos = 0; string text = node.Text; if (childCount > 0) { System.Globalization.CompareInfo compare = System.Windows.Forms.Application.CurrentCulture.CompareInfo; // Simple optimization if added in sort order if (compare.Compare(children[(childCount - 1)].Text, text) <= 0) pos = childCount; else { // Binary Search int i = 0; int j = childCount; while (i < j) { int mid = (i + j) / 2; if (compare.Compare(children[mid].Text, text) <= 0) i = mid + 1; else i = mid; } pos = i; } } node.SortChildren(); InsertNodeAt(pos, node); if (treeView != null && node == treeView.SelectedNode) { treeView.SelectedNode = node; } return pos; }
private void SortChildren() { if (childCount > 0) { TreeNodeEx[] sort = new TreeNodeEx[childCount]; CompareInfo compare = System.Windows.Forms.Application.CurrentCulture.CompareInfo; for (int i = 0; i < childCount; i++) { int pos = -1; for (int j = 0; j < childCount; j++) { if (children[j] != null) { if (pos == -1 || compare.Compare(children[j].Text, children[pos].Text) < 0) { pos = j; } } } sort[i] = children[pos]; children[pos] = null; sort[i].index = i; sort[i].SortChildren(); } children = sort; } }
internal void InsertNodeAt(int index, TreeNodeEx node) { SizeChildrenArray(); node.parent = this; node.index = index; node.treeView = treeView; for (int i = childCount; i > index; i--) { TreeNodeEx node1 = children[i - 1]; node1.index = i; children[i] = node1; } childCount++; children[index] = node; if (treeView != null) { if (childCount == 1 && IsVisible) { Invalidate(); } else if (index != 0 && expanded && children[index - 1].IsVisible) { treeView.InvalidateDown(node); } } }
public virtual TreeNodeEx Add(string text) { TreeNodeEx node = new TreeNodeEx(text); Add(node); return(node); }
private void SetNodeOwner(TreeNodeEx node) { node.treeView = owner.TreeView; foreach (TreeNodeEx tn in node.Nodes) { SetNodeOwner(tn); } }
public virtual bool CanDropUnder(TreeNodeEx nodeToDrop) { int count = (Parent != null) ? Parent.Nodes.Count : TreeView.Nodes.Count; if (count > 0 && IsExpanded) return true; return Index == count - 1; }
public virtual void Insert(int index, TreeNodeEx node) { TreeViewEx treeView = owner.TreeView; if (treeView != null && treeView.Sorted) { owner.AddSorted(node); } owner.InsertNodeAt(index, node); }
public int IndexOf(TreeNodeEx node) { for (int i = 0; i < Count; i++) { if (this[i] == node) { return(i); } } return(-1); }
internal void SizeChildrenArray() { if (children == null) { children = new TreeNodeEx[10]; } else if (childCount == children.Length) { TreeNodeEx[] copy = new TreeNodeEx[childCount * 2]; Array.Copy(children, 0, copy, 0, childCount); children = copy; } }
public virtual object Clone() { TreeNodeEx node = new TreeNodeEx(text, imageIndex, selectedImageIndex); if (childCount > 0) { node.children = new TreeNodeEx[childCount]; for (int i = 0; i < childCount; i++) node.Nodes.Add(children[i].Clone() as TreeNodeEx); } node.Checked = Checked; node.Tag = Tag; return node; }
private void RemoveRecurse() { // Remove children. // FIXME: why? /*for (int i = 0; i < childCount; i++) { children[i].RemoveRecurse(); }*/ // Remove out of parent's children. for (int i = index; i < parent.childCount - 1; i++) { TreeNodeEx node = parent.children[i + 1]; node.index = i; parent.children[i] = node; } parent.childCount--; parent = null; treeView = null; }
public void Expand() { if (expanded) { return; } TreeNodeEx node = this; node.expanded = true; if (treeView == null) { return; } TreeNodeEx highestNode = node; for (; node != null; node = node.Parent) { node.expanded = true; highestNode = node; } treeView.InvalidateDown(highestNode); }
public void Remove() { // If we need to, redraw the parent. if (treeView != null) treeView.InvalidateDown(this); // When removing a node, we need to see if topNode is it or its children. // If so we find a new topNode. TreeNodeEx node = treeView.topNode; while (node != null) { if (node == this) { treeView.topNode = PrevVisibleNode; break; } node = node.parent; } OnNodeMoved(new TreeNodeExMovedEventArgs(this, new TreeNodeExParent(this.parent), null)); RemoveRecurse(); }
public virtual int Add(TreeNodeEx node) { if (node.treeView != null && node.treeView.Sorted) { return(owner.AddSorted(node)); } else { owner.SizeChildrenArray(); SetNodeOwner(node); node.parent = owner; node.OnNodeMoved(new TreeNodeExMovedEventArgs(node, null, new TreeNodeExParent(owner))); int pos = owner.childCount++; node.index = pos; owner.children[node.index] = node; // Redraw if required. if (node.treeView != null && node.treeView.IsHandleCreated) { node.treeView.Draw(owner); } return(pos); } }
void ProcessClick(int x, int y, bool rightMouse) { int nodeFromTop = -1; int height = ItemHeight; using (Graphics g = CreateGraphics()) { // Iterate through all the nodes, looking for the bounds that match. NodeEnumeratorEx nodes = new NodeEnumeratorEx(this.nodes); while (nodes.MoveNext()) { if (nodes.currentNode == topNode) { // We are now at the top of the control. nodeFromTop = 0; } if (nodeFromTop > -1) { // Check if the y matches this node. if (y < height * (nodeFromTop + 1)) { bool allowEdit = false; bool allowSelect = true; // Clicking the image can be used to select. if (imageList == null || !GetImageBounds(nodeFromTop, nodes.level).Contains(x, y)) { // Clicking the text can be used to edit and select. // if false then the hierarchy marker must have been clicked. if (GetTextBounds(g, nodes.currentNode, nodeFromTop, nodes.level).Contains(x, y)) { allowEdit = true; } else { allowSelect = false; } } if (SelectedNode == nodes.Current && mouseClickTimer != null && mouseClickTimer.Enabled && (allowEdit || allowSelect)) { mouseClickTimer.Stop(); nodeToEdit = null; nodes.currentNode.Toggle(); return; } if (allowSelect || rightMouse) { if (selectedNode == nodes.Current) { if (labelEdit && allowEdit && !rightMouse) { if (selectedNode.CanRename()) nodeToEdit = nodes.currentNode; } Focus(); } else { nodeToEdit = null; // Do the events. TreeViewExCancelEventArgs eventArgs = new TreeViewExCancelEventArgs(nodes.currentNode, false, TreeViewExAction.ByMouse); OnBeforeSelect(eventArgs); if (!eventArgs.Cancel) { SelectedNode = nodes.currentNode; Focus(); } } if (rightMouse) { return; } if (mouseClickTimer == null) { mouseClickTimer = new Forms.Timer(); mouseClickTimer.Tick +=new EventHandler(mouseClickTimer_Tick); mouseClickTimer.Interval = mouseEditTimeout; } mouseClickTimer.Start(); break; } } nodeFromTop++; } } } }
// This handles the timeout on the click timer and begins an edit. private void mouseClickTimer_Tick(object sender, EventArgs e) { mouseClickTimer.Stop(); if (nodeToEdit != null) { nodeToEdit.BeginEdit(); nodeToEdit = null; } }
public TreeViewEx() : base() { hideSelection = true; indent = 19; itemHeight = -1; scrollable = true; showLines = true; showPlusMinus = true; showRootLines = true; root = new TreeNodeEx(this); root.Expand(); nodes = new TreeNodeExCollection(root); BackColor = SystemColors.Window; ForeColor = SystemColors.WindowText; SetStyle(Forms.ControlStyles.StandardClick, false); // Switch on double buffering. SetStyle(Forms.ControlStyles.DoubleBuffer | Forms.ControlStyles.AllPaintingInWmPaint | Forms.ControlStyles.UserPaint, true); }
internal void EndEdit(bool cancel) { if (!cancel) { editNode.Text = textBox.Text; editNode.OnRenamed(); } textBox.Visible = false; editNode = null; if (hScrollBar != null) { hScrollBar.Value = xScrollValueBeforeEdit; } }
// Reset the enumeration. public void Reset() { first = true; currentNode = null; level = 0; }
internal void BeginEdit(TreeNodeEx node) { editNode = node; if (textBox == null) { textBox = new Forms.TextBox(); textBox.BorderStyle = Forms.BorderStyle.FixedSingle; textBox.Visible = false; Controls.Add(textBox); textBox.Leave +=new EventHandler(textBox_Leave); textBox.KeyUp +=new Forms.KeyEventHandler(textBox_KeyUp); } textBox.Text = editNode.Text; RectangleF nodeBounds = node.Bounds; nodeBounds.Y -= 2; float y = nodeBounds.Y + (nodeBounds.Height - textBox.Height) /2; // Resize the text bounds to cover the area we want to clear. nodeBounds.X -= 2; nodeBounds.Height += 4; nodeBounds.Width += 4; if (hScrollBar != null) { xScrollValueBeforeEdit = hScrollBar.Value; } int x = (int)nodeBounds.X; int width = GetTextBoxWidth(ref x); textBox.AutoSize = false; textBox.SetBounds(x + 2, (int)y + 2, width, 17); textBox.Visible = true; textBox.Focus(); textBox.SelectAll(); // Redraw to hide the node we are editing. Draw(editNode); }
public TreeNodeExParent(TreeNodeEx node) { IsNode = true; Node = node; TreeView = null; }
public virtual bool CanDropAbove(TreeNodeEx nodeToDrop) { return true; }
public bool Contains(TreeNodeEx node) { return IndexOf(node) != -1; }
public TreeNodeExMovedEventArgs(TreeNodeEx node, TreeNodeExParent oldParent, TreeNodeExParent newParent) { Node = node; OldParent = oldParent; NewParent = newParent; }
internal TreeNodeExCollection(TreeNodeEx owner) { this.owner = owner; }
public void Remove(TreeNodeEx node) { node.Remove(); }
private void vScrollBar_ValueChanged(object sender, EventArgs e) { int nodeFromTop = 0; NodeEnumeratorEx nodes = new NodeEnumeratorEx(this.nodes); while (nodes.MoveNext()) { if (nodeFromTop == vScrollBar.Value) { topNode = nodes.currentNode; Invalidate(); return; } nodeFromTop++; } }
public TreeViewExEventArgs(TreeNodeEx node) { this.node = node; this.action = TreeViewExAction.Unknown; }
// Move to the next element in the enumeration order. public bool MoveNext() { if (first) { if (nodes.Count == 0) { return false; } currentNode = nodes[0]; first = false; return true; } if (currentNode == null) { return false; } if (currentNode.childCount > 0 && currentNode.expanded) { // If expanded climb into hierarchy. currentNode = currentNode.Nodes[0]; level++; } else { TreeNodeEx nextNode = currentNode.NextNode; TreeNodeEx nextCurrentNode = currentNode; while (nextNode == null) { // We need to move back up. // Are we back at the top? if (nextCurrentNode.Parent == null) { // Leave the nextNode as the previous last node. nextNode = currentNode; return false; } else { nextCurrentNode = nextCurrentNode.Parent; if (nextCurrentNode.parent != null) { nextNode = nextCurrentNode.NextNode; } level--; } } currentNode = nextNode; } return true; }
public RectangleF GetNodeBounds(TreeNodeEx node) { if (node.parent != null) { int nodeFromTop = -1; NodeEnumeratorEx nodes = new NodeEnumeratorEx(this.nodes); while (nodes.MoveNext()) { if (nodes.currentNode == topNode) { // We are at the top of the control. nodeFromTop = 0; } if (nodes.currentNode == node) { using (Graphics g = CreateGraphics()) { return GetTextBounds(g, node, nodeFromTop, nodes.level); } } if (nodeFromTop >= 0) { nodeFromTop++; } } } return Rectangle.Empty; }
// Constructors. public NodeLabelExEditEventArgs(TreeNodeEx node) { this.node = node; }
// Render the treeview starting from startingLine internal void Draw(Graphics g, TreeNodeEx startNode) { if (updating > 0) { return; } Rectangle clientRectangle = ClientRectangle; int drawableHeight = clientRectangle.Height; int drawableWidth = clientRectangle.Width - xOffset; // We count the visible rows to see if we need the v scrollbar but we wait before deciding if we need the h scroll bar. bool needsHScrollBar = false; bool needsVScrollBar = GetNeedVScrollBar() && scrollable; bool createNewVScrollBar = false; bool createNewHScrollBar = false; if (needsVScrollBar) { // Don't allow drawing on the area that is going to be the scroll bar. // Create the scroll bar so we can get its width. if (vScrollBar == null) { vScrollBar = new Forms.VScrollBar(); createNewVScrollBar = true; } drawableWidth -= vScrollBar.Width; Rectangle rect = new Rectangle(drawableWidth + xOffset, 0, vScrollBar.Width, clientRectangle.Height); g.ExcludeClip(rect); } else { // Check to see if the top node is not the first node and we have room for the whole tree. // If so, abandon the draw and redraw the whole tree from the top. if (topNode != null && topNode != this.nodes[0]) { topNode = null; Invalidate(); return; } if (vScrollBar != null) { // We don't need the scroll bar anymore. Controls.Remove(vScrollBar); vScrollBar.Dispose(); vScrollBar = null; } } // Is the node being processed on the screen. bool drawing = false; // Start counting from the top. int nodeFromTop = -1; // Number of nodes. int nodeCount = 0; int topNodePosition = 0; // The maximum width of a displayed node. float maxWidth = 0; //StringFormat format = new StringFormat(StringFormatFlags.NoWrap); if (topNode == null && this.nodes.Count > 0) { topNode = this.nodes[0]; } RectangleF textBounds = Rectangle.Empty; NodeEnumeratorEx nodes = new NodeEnumeratorEx(this.nodes); using (Pen markerPen = new Pen(SystemColors.ControlDarkDark)) { markerPen.DashStyle = DashStyle.Dot; while (nodes.MoveNext()) { // If we havnt started drawing yet, then see if we need to and if so clear the background. if (!drawing) { if (nodes.currentNode == topNode) { // We are at the top node. nodeFromTop = 0; topNodePosition = nodeCount; } // Check to see if we must start drawing. Clear the background. if (nodeFromTop >= 0 && (nodes.currentNode == startNode || startNode == root)) { // Clear background. int y = ItemHeight * nodeFromTop; using (SolidBrush b = new SolidBrush(BackColor)) { g.FillRectangle(b, 0, y, ClientSize.Width, ClientSize.Height - y); } drawing = true; } } // Even if we arnt drawing nodes yet, we need to measure if the nodes are visible, for hscrollbar purposes. if (nodeFromTop >= 0 && drawableHeight > 0) { textBounds = GetTextBounds(g, nodes.currentNode, nodeFromTop, nodes.level); // Is the text too wide to fit in - if so we need an h scroll bar. if (textBounds.Right > drawableWidth && !needsHScrollBar && scrollable) { needsHScrollBar = true; if (hScrollBar == null) { hScrollBar = new Forms.HScrollBar(); createNewHScrollBar = true; } drawableHeight -= hScrollBar.Height; // Don't allow drawing on the area that is going to be the scroll bar. Rectangle rect = new Rectangle(0, clientRectangle.Height - hScrollBar.Height, clientRectangle.Width, hScrollBar.Height); g.ExcludeClip(rect); } if (textBounds.Right > maxWidth) { maxWidth = textBounds.Right; } } // Draw the node if we still have space. if (drawing && drawableHeight > 0) { RectangleF bounds; // Draw the lines and the expander. DrawExpanderMarker(g, markerPen, nodes.currentNode, nodeFromTop, nodes.level); // Draw checkboxes. if (checkBoxes) { bounds = GetCheckBounds(nodeFromTop, nodes.level); Forms.ButtonState state; if (nodes.currentNode.isChecked) { state = Forms.ButtonState.Checked; } else { state = Forms.ButtonState.Normal; } Forms.ControlPaint.DrawCheckBox(g, RectIFromRectF(bounds), state); } // Draw the node image. if (imageList != null) { bounds = GetImageBounds(nodeFromTop, nodes.level); int index = GetDisplayIndex(nodes.currentNode); if (index < imageList.Images.Count && index >= 0) { Image image = imageList.Images[index]; g.DrawImage(image, bounds.X, bounds.Y); } } bounds = textBounds; // The height may be too small now. // If we are currently editing a node then dont draw it. if (drawableHeight > 0 && nodes.currentNode != editNode) { // Draw the node text. var bnds = RectIFromRectF(bounds); if (selectedDropNode == nodes.currentNode) { if (dragMoveDirection == DragMoveDirection.Above) g.DrawLine(Pens.Black, new PointF(bnds.X, bnds.Y), new PointF(bnds.X + bnds.Width, bnds.Y)); else if (dragMoveDirection == DragMoveDirection.Below) g.DrawLine(Pens.Black, new PointF(bnds.X, bnds.Y + bnds.Height), new PointF(bnds.X + bnds.Width, bnds.Y + bnds.Height)); else g.FillRectangle(SystemBrushes.Highlight, bnds); } if ((selectedDropNode == nodes.currentNode && dragMoveDirection == DragMoveDirection.On) || (((nodeToBeDropped == null && nodes.currentNode == selectedNode) || (nodes.currentNode == nodeToBeDropped)) && (Focused || !hideSelection))) { // TODO: FullRowSelect g.FillRectangle(SystemBrushes.Highlight, bnds); Forms.TextRenderer.DrawText(g, nodes.currentNode.Text, Font, bnds, SystemColors.HighlightText, Forms.TextFormatFlags.NoClipping); // Draw the focus rectangle. Rectangle r = new Rectangle((int)(bounds.X), (int)(bounds.Y), (int)(bounds.Width), (int)(bounds.Height)); Forms.ControlPaint.DrawFocusRectangle(g, r); } else { Forms.TextRenderer.DrawText(g, nodes.currentNode.Text, Font, bnds, SystemColors.ControlText, Forms.TextFormatFlags.NoClipping); } } drawableHeight -= ItemHeight; } if (nodeFromTop >= 0) { nodeFromTop++; } nodeCount++; } } // If we need a v scroll bar, then set it up. if (needsVScrollBar) { SetupVScrollBar(nodeCount, needsHScrollBar, createNewVScrollBar, topNodePosition); } if (needsHScrollBar) { SetupHScrollBar(needsVScrollBar, (int)maxWidth, createNewHScrollBar, g); } else if (hScrollBar != null) { // We dont need the scroll bar. // If we have scrolled then we need to reset the position. if (xOffset != 0) { xOffset = 0; Invalidate(); } Controls.Remove(hScrollBar); hScrollBar.Dispose(); hScrollBar = null; } }
public void EnsureVisible() { TreeViewEx.NodeEnumeratorEx nodes; int nodeFromTop; int nodeNo; while (true) { // Find "this" node number and position from the top control. nodeFromTop = -1; nodeNo = 0; bool nodeFound = false; nodes = new TreeViewEx.NodeEnumeratorEx(treeView.nodes); while (nodes.MoveNext()) { if (nodes.currentNode == treeView.topNode) { // We are at the top of the control. nodeFromTop = 0; } if (nodes.currentNode == this) { if (nodeFromTop < 0) { treeView.topNode = this; treeView.Invalidate(); return; } nodeFound = true; break; } if (nodeFromTop >= 0) { nodeFromTop++; } nodeNo++; } if (nodeFound) { break; } else { // Make sure all parents are expanded and see if its now visible. TreeNodeEx node = this; TreeNodeEx highestNode = node; for (; node != null; node = node.Parent) { node.expanded = true; highestNode = node; } treeView.InvalidateDown(highestNode); } } int visibleNodes = treeView.VisibleCountActual; // See if its already visible. if (nodeFromTop < visibleNodes) { return; } // Set the top node no we want to make this node 1 up from the bottom. nodeFromTop = nodeNo - visibleNodes + 1; if (nodeFromTop < 0) { nodeFromTop = 0; } // Find the node corresponding to this node no. nodes.Reset(); nodeNo = 0; while (nodes.MoveNext()) { if (nodeFromTop == nodeNo) { treeView.topNode = nodes.currentNode; treeView.Invalidate(); break; } nodeNo++; } }
// Draw from startNode downwards internal void Draw(TreeNodeEx startNode) { if (!Created || !Visible) return; using (Graphics g = CreateGraphics()) { Draw(g, startNode); } }
bool HasParent(TreeNodeEx check, TreeNodeEx parent) { var node = check; while (node != null) { if (node == parent) return true; node = node.Parent; } return false; }
// Get the bounds of a node. Supply a Graphics to measure the text, the node being measured, the number of the node being measured in the list of those being shown, the number of the node that is the first to be displayed (topNode) and the level of x indent. internal RectangleF GetTextBounds(Graphics g, TreeNodeEx node, int nodeFromTop, int level) { int height = ItemHeight; int y = height * nodeFromTop; // Calculate the basic offset from the level and the indent. int x = (level + 1) * indent - xOffset; // Add on the width of the image if applicable. if (imageList != null) { x += imageList.ImageSize.Width + imagePad; } // Add on the width of the checkBoxes if applicable. if (checkBoxes) { x += checkSize; } Font font; if (node.nodeFont == null) { font = Font; } else { font = node.nodeFont; } float width = g.MeasureString(node.text, font).Width; if (width < 5) width = 5; return new RectangleF(x, y, width, height); }
public int IndexOf(TreeNodeEx node) { for (int i = 0; i < Count; i++) { if (this[i] == node) { return i; } } return -1; }
public bool Contains(TreeNodeEx node) { return(IndexOf(node) != -1); }
// Invalidate from startNode down. internal void InvalidateDown(TreeNodeEx startNode) { if (updating > 0 || this.nodes == null) { return; } // Find the position of startNode relative to the top node. int nodeFromTop = -1; NodeEnumeratorEx nodes = new NodeEnumeratorEx(this.nodes); while (nodes.MoveNext()) { if (nodes.currentNode == topNode) { // We are at the top of the control. nodeFromTop = 0; } if (nodes.currentNode == startNode) { break; } if (nodeFromTop >= 0) { nodeFromTop++; } } // Calculate the y position of startNode. int y = nodeFromTop * ItemHeight; // Invalidate from this position down. // Start one pixel higher to cover the focus rectangle. Invalidate(new Rectangle(0, y - 1, ClientRectangle.Width, ClientRectangle.Height - y + 1)); }
// Emulate the Microsoft behaviour of resetting the control when they have to recreate the handle. internal void ResetView() { topNode = null; CollapseAll(); Draw(root); }
protected Forms.OwnerDrawPropertyBag GetItemRenderStyles(TreeNodeEx node, int state) { // TODO: Property Bag return null; }
// Constructor. public TreeViewExEventArgs(TreeNodeEx node, TreeViewExAction action) { this.node = node; this.action = action; }
// Non Microsoft member. protected override void OnMouseDown(Forms.MouseEventArgs e) { nodeToEdit = null; if (e.Button == Forms.MouseButtons.Left) { int nodeFromTop = -1; // Iterate through all the nodes, looking for the bounds that match. NodeEnumeratorEx nodes = new NodeEnumeratorEx(this.nodes); bool _clicked = false; while (nodes.MoveNext()) { if (nodes.currentNode == topNode) { // We are now at the top of the control. nodeFromTop = 0; } if (nodeFromTop > -1) { if (GetExpanderBounds(nodeFromTop, nodes.level).Contains(e.X, e.Y)) { nodes.currentNode.Toggle(); _clicked = true; break; } else if (GetCheckBounds(nodeFromTop, nodes.level).Contains(e.X, e.Y)) { TreeViewExCancelEventArgs args = new TreeViewExCancelEventArgs(nodes.currentNode, false, TreeViewExAction.ByMouse); OnBeforeCheck(args); if (!args.Cancel) { nodes.currentNode.isChecked = !nodes.currentNode.isChecked; OnAfterCheck(new TreeViewExEventArgs(nodes.currentNode, TreeViewExAction.ByMouse)); } Invalidate(GetCheckBounds(nodeFromTop, nodes.level)); _clicked = true; break; } nodeFromTop++; } } if (!_clicked) { var pt = new Point(e.X, e.Y); var node = GetNodeAt(e.X, e.Y); if (node != null && node.Bounds.Contains(pt)) { Focus(); nodeToBeDropped = node; if (selectedNode != null) selectedNode.Invalidate(); nodeToBeDropped.Invalidate(); } } } else { ProcessClick(e.X, e.Y, true); } base.OnMouseDown(e); }
protected override bool ProcessDialogKey(Forms.Keys keyData) { if ((keyData & Forms.Keys.Alt) == 0) { Forms.Keys key = keyData & Forms.Keys.KeyCode; bool shiftKey = (keyData & Forms.Keys.Shift) != 0; bool controlKey = (keyData & Forms.Keys.Control) != 0; TreeNodeEx selectedNode = SelectedNode; switch (key) { case Forms.Keys.Left: if (selectedNode != null) { if (selectedNode.IsExpanded) { selectedNode.Collapse(); } else if (selectedNode.Parent != null) { SelectedNode = selectedNode.Parent; } } return true; case Forms.Keys.Right: if (selectedNode != null && selectedNode.Nodes.Count != 0) { if (selectedNode.IsExpanded) { SelectedNode = selectedNode.NextVisibleNode; } else { selectedNode.Expand(); } } return true; case Forms.Keys.Up: if (selectedNode != null) { selectedNode = selectedNode.PrevVisibleNode; if (selectedNode != null) { SelectedNode = selectedNode; } } return true; case Forms.Keys.Down: if (selectedNode != null) { selectedNode = selectedNode.NextVisibleNode; if (selectedNode != null) { SelectedNode = selectedNode; } } return true; case Forms.Keys.Home: if (Nodes[0] != null) { SelectedNode = Nodes[0]; } return true; case Forms.Keys.End: { NodeEnumeratorEx nodes = new NodeEnumeratorEx(this.nodes); while (nodes.MoveNext()) { } SelectedNode = nodes.currentNode; return true; } case Forms.Keys.Prior: { int nodePosition = 0; // Get the position of the current selected node. NodeEnumeratorEx nodes = new NodeEnumeratorEx(this.nodes); while (nodes.MoveNext()) { if (nodes.currentNode == selectedNode) { break; } nodePosition++; } nodePosition -= VisibleCountActual - 1; if (nodePosition < 0) { nodePosition = 0; } // Get the node that corresponds to the position. nodes.Reset(); while (nodes.MoveNext()) { if (nodePosition-- == 0) { break; } } // Set the selectedNode. SelectedNode = nodes.currentNode; } return true; case Forms.Keys.Next: { int rows = 0; int rowsPerPage = VisibleCountActual; NodeEnumeratorEx nodes = new NodeEnumeratorEx(this.nodes); while (nodes.MoveNext()) { if (nodes.currentNode == selectedNode || rows > 0) { rows++; if (rows >= rowsPerPage) { break; } } } SelectedNode = nodes.currentNode; return true; } } } return base.ProcessDialogKey(keyData); }
// Constructor. public TreeViewExCancelEventArgs(TreeNodeEx node, bool cancel, TreeViewExAction action) : base(cancel) { this.node = node; this.action = action; }
private void DrawExpanderMarker(Graphics g, Pen markerPen, TreeNodeEx node, int nodeFromTop, int level) { Rectangle bounds = GetExpanderBounds(nodeFromTop, level); int midX = bounds.X + 4; int midY = bounds.Y + bounds.Height / 2; int lineRightStart = midX; int lineTopEnd = midY; if (node.Nodes.Count > 0 && showPlusMinus) { GraphicsPath path = new GraphicsPath(); { if (!node.IsExpanded) _closedRenderer.DrawBackground(g, new Rectangle(midX - 4, midY - 4, 10, 10)); else _openedRenderer.DrawBackground(g, new Rectangle(midX - 4, midY - 4, 10, 10)); } lineRightStart += 6; lineTopEnd -= 6; } if (!showLines) { return; } // Draw the right lead line if (bounds.Right > lineRightStart) g.DrawLine(markerPen, lineRightStart, midY, bounds.Right - 6, midY); // Draw the top lead line TreeNodeEx lineNode = node.PrevNode; if (lineNode == null) lineNode = node.Parent; if (lineNode != null) g.DrawLine(markerPen, midX, lineNode.markerLineY + 2, midX, lineTopEnd); if (node.Nodes.Count > 0) node.markerLineY = midY + 6; else node.markerLineY = midY; }
public NodeLabelExEditEventArgs(TreeNodeEx node, String label) { this.node = node; this.label = label; }
// Get the node image index to display depending on what is set. private int GetDisplayIndex(TreeNodeEx node) { int index = -1; if (node == selectedNode) { if (node.SelectedImageIndex > -1) index = node.SelectedImageIndex; else if (selectedImageIndex > -1) index = selectedImageIndex; else if (this.imageIndex > -1) index = this.imageIndex; } else { if (node.ImageIndex > -1) index = node.ImageIndex; else if (this.imageIndex > -1) index = this.imageIndex; } return index; }