/// <summary> /// Gets the next visible node. /// </summary> /// <param name="cCurNode"></param> /// <returns>Returns TRUE if already on the last node</returns> private bool GetNextNode(ref TreeListNode cCurNode) { if (cCurNode == null) return true; if (cCurNode.IsExpanded && cCurNode.Children > 0) { cCurNode = (TreeListNode)cCurNode.FirstChild(); return false; } else if (cCurNode.NextSibling() == null && cCurNode.ParentNode() != null) { TreeListNode t = cCurNode; do { t = (TreeListNode)t.ParentNode(); if (t.NextSibling() != null) { cCurNode = (TreeListNode)t.NextSibling(); return false; } } while (t.NextSibling() == null && t.ParentNode() != null); } else if (cCurNode.NextSibling() != null) { cCurNode = (TreeListNode)cCurNode.NextSibling(); return false; } return true; }
private void RenderNodeRows(TreeListNode node, Graphics g, Rectangle r, ref int totalRend) { // Get handy references TreeListNodeCollection nodesParent = ((TreeListNode)node.ParentNode()).Nodes; TreeListNode nodePreviousSibling = ((TreeListNode)node.PreviousSibling()); // Set working variables int childCount = 0; if (nodePreviousSibling != null) childCount = nodePreviousSibling.GetVisibleNodeCount; int count = nodesParent.Count; int index = nodesParent.IndexOf(node); int level = node.Level(); if (node.IsVisible) { int eb = 10; // edge buffer // only render if row is visible in viewport if (((r.Top + itemheight * totalRend + eb / 4 + itemheight >= r.Top + 2) && (r.Top + itemheight * totalRend + eb / 4 < r.Top + r.Height))) { rendcnt++; int lb = 0; // level buffer int ib = 0; // icon buffer int hb = headerBuffer; // header buffer Pen linePen = new Pen(SystemBrushes.ControlDark, 1.0f); Pen PMPen = new Pen(SystemBrushes.ControlDark, 1.0f); Pen PMPen2 = new Pen(new SolidBrush(Color.Black), 1.0f); linePen.DashStyle = DashStyle.Dot; // add space for plis/minus icons and/or root lines to the edge buffer if (showrootlines || showplusminus) { eb += 10; } // set level buffer lb = indent * level; // set icon buffer if ((node.Selected || node.Focused) && stateImageList != null) { if (node.ImageIndex >= 0 && node.ImageIndex < stateImageList.Images.Count) { stateImageList.Draw(g, r.Left + lb + eb + 2 - hscrollBar.Value, r.Top + hb + itemheight * totalRend + eb / 4 - 2, 16, 16, node.ImageIndex); ib = 18; } } else { if (smallImageList != null && node.ImageIndex >= 0 && node.ImageIndex < smallImageList.Images.Count) { smallImageList.Draw(g, r.Left + lb + eb + 2 - hscrollBar.Value, r.Top + hb + itemheight * totalRend + eb / 4 - 2, 16, 16, node.ImageIndex); ib = 18; } } // add a rectangle to the node row rectangles Rectangle sr = new Rectangle(r.Left + lb + ib + eb + 4 - hscrollBar.Value, r.Top + hb + itemheight * totalRend + 2, allColsWidth - (lb + ib + eb + 4), itemheight); nodeRowRects.Add(sr, node); int iColWidth = (columns[0].ScaleStyle == ColumnScaleStyle.Spring ? springWid : columns[0].Width); // BMS 2003-05-24 // render per-item background if (node.BackColor != this.BackColor) { if (node.UseItemStyleForSubItems) g.FillRectangle(new SolidBrush(node.BackColor), r.Left + lb + ib + eb + 4 - hscrollBar.Value, r.Top + hb + itemheight * totalRend + 2, allColsWidth - (lb + ib + eb + 4), itemheight); else g.FillRectangle(new SolidBrush(node.BackColor), r.Left + lb + ib + eb + 4 - hscrollBar.Value, r.Top + hb + itemheight * totalRend + 2, iColWidth /* BMS 2003-05-24 columns[0].Width */ - (lb + ib + eb + 4), itemheight); } g.Clip = new Region(sr); // render selection and focus if (node.Selected && isFocused) { g.FillRectangle(new SolidBrush(rowSelectColor), sr); } else if (node.Selected && !isFocused && !hideSelection) { g.FillRectangle(SystemBrushes.Control, sr); } else if (node.Selected && !isFocused && hideSelection) { ControlPaint.DrawFocusRectangle(g, sr); } if (node.Focused && ((isFocused && multiSelect) || !node.Selected)) { ControlPaint.DrawFocusRectangle(g, sr); } g.Clip = new Region(new Rectangle(r.Left + 2 - hscrollBar.Value, r.Top + hb + 2, iColWidth /* BMS 2003-05-23 columns[0].Width */, r.Height - hb - 4)); // render root lines if visible bool bMoreSiblingNodes = node.NextSibling() != null; if (r.Left + eb - hscrollBar.Value > r.Left) { if (showrootlines && level == 0) { if (index == 0) { // Draw horizontal line with a length of eb/2 g.DrawLine(linePen, r.Left + eb / 2 - hscrollBar.Value, r.Top + eb / 2 + hb, r.Left + eb - hscrollBar.Value, r.Top + eb / 2 + hb); if (bMoreSiblingNodes) // Draw vertial line with a length of eb/2 g.DrawLine(linePen, r.Left + eb / 2 - hscrollBar.Value, r.Top + eb / 2 + hb, r.Left + eb / 2 - hscrollBar.Value, r.Top + eb + hb); } else if (index == count - 1) { // Draw horizontal line with a length of eb/2 offset vertically by itemHeight*totalrend g.DrawLine(linePen, r.Left + eb / 2 - hscrollBar.Value, r.Top + eb / 2 + hb + itemheight * (totalRend), r.Left + eb - hscrollBar.Value, r.Top + eb / 2 + hb + itemheight * (totalRend)); // if (bMoreSiblingNodes) // Draw vertial line with a length of eb/2 offset vertically by itemHeight*totalrend g.DrawLine(linePen, r.Left + eb / 2 - hscrollBar.Value, r.Top + hb + itemheight * (totalRend), r.Left + eb / 2 - hscrollBar.Value, r.Top + eb / 2 + hb + itemheight * (totalRend)); } else { // Draw horizontal line with a length of eb/2 offset vertically by itemHeight*totalrend g.DrawLine(linePen, r.Left + eb / 2 - hscrollBar.Value, r.Top + eb + hb + itemheight * (totalRend) - eb / 2, r.Left + eb - hscrollBar.Value, r.Top + eb + hb + itemheight * (totalRend) - eb / 2); if (bMoreSiblingNodes) // Draw vertial line with a length of eb/2 offset vertically by itemHeight*totalrend g.DrawLine(linePen, r.Left + eb / 2 - hscrollBar.Value, r.Top + eb + hb + itemheight * (totalRend - 1), r.Left + eb / 2 - hscrollBar.Value, r.Top + eb + hb + itemheight * (totalRend)); } if (childCount > 0) g.DrawLine(linePen, r.Left + eb / 2 - hscrollBar.Value, r.Top + hb + itemheight * (totalRend - childCount), r.Left + eb / 2 - hscrollBar.Value, r.Top + hb + itemheight * (totalRend)); } } // render child lines if visible if (r.Left + lb + eb - hscrollBar.Value > r.Left) { if (showlines && level > 0) { if (index == count - 1) { g.DrawLine(linePen, r.Left + lb + eb / 2 - hscrollBar.Value, r.Top + eb / 2 + hb + itemheight * (totalRend), r.Left + lb + eb - hscrollBar.Value, r.Top + eb / 2 + hb + itemheight * (totalRend)); // if (bMoreSiblingNodes) g.DrawLine(linePen, r.Left + lb + eb / 2 - hscrollBar.Value, r.Top + hb + itemheight * (totalRend), r.Left + lb + eb / 2 - hscrollBar.Value, r.Top + eb / 2 + hb + itemheight * (totalRend)); } else { g.DrawLine(linePen, r.Left + lb + eb / 2 - hscrollBar.Value, r.Top + eb / 2 + hb + itemheight * (totalRend), r.Left + lb + eb - hscrollBar.Value, r.Top + eb / 2 + hb + itemheight * (totalRend)); // if (bMoreSiblingNodes) g.DrawLine(linePen, r.Left + lb + eb / 2 - hscrollBar.Value, r.Top + hb + itemheight * (totalRend), r.Left + lb + eb / 2 - hscrollBar.Value, r.Top + eb + hb + itemheight * (totalRend)); } if (childCount > 0) g.DrawLine(linePen, r.Left + lb + eb / 2 - hscrollBar.Value, r.Top + hb + itemheight * (totalRend - childCount), r.Left + lb + eb / 2 - hscrollBar.Value, r.Top + hb + itemheight * (totalRend)); } } // render +/- signs if visible if (r.Left + lb + eb / 2 + 5 - hscrollBar.Value > r.Left) { if (showplusminus && (node.Children > 0 || alwaysShowPM)) { if (index == 0 && level == 0) { RenderPlus(g, r.Left + lb + eb / 2 - 4 - hscrollBar.Value, r.Top + hb + eb / 2 - 4, 8, 8, node); } else if (index == count - 1) { RenderPlus(g, r.Left + lb + eb / 2 - 4 - hscrollBar.Value, r.Top + hb + itemheight * totalRend + eb / 2 - 4, 8, 8, node); } else { RenderPlus(g, r.Left + lb + eb / 2 - 4 - hscrollBar.Value, r.Top + hb + itemheight * totalRend + eb / 2 - 4, 8, 8, node); } } } // render text if visible if (r.Left + iColWidth /* BMS 2003-05024 columns[0].Width */ - hscrollBar.Value > r.Left) { if (node.Selected && isFocused) g.DrawString(TruncatedString(node.Text, columns[0].Width, lb + eb + ib + 6, g), Font, SystemBrushes.HighlightText, (float)(r.Left + lb + ib + eb + 4 - hscrollBar.Value), (float)(r.Top + hb + itemheight * totalRend + eb / 4)); else g.DrawString(TruncatedString(node.Text, columns[0].Width, lb + eb + ib + 6, g), Font, new SolidBrush(node.ForeColor), (float)(r.Left + lb + ib + eb + 4 - hscrollBar.Value), (float)(r.Top + hb + itemheight * totalRend + eb / 4)); } // render subitems int j; int last = 0; if (columns.Count > 0) { for (j = 0; j < node.SubItems.Count && j < columns.Count; j++) { iColWidth = (columns[j].ScaleStyle == ColumnScaleStyle.Spring ? springWid : columns[j].Width); // BMS 2003-05-24 int iColPlus1Width = (columns[j + 1].ScaleStyle == ColumnScaleStyle.Spring ? springWid : columns[j + 1].Width); // BMS 2003-05-24 last += iColWidth /* BMS 2003-05-24 columns[j].Width */; g.Clip = new Region(new Rectangle(last + 6 - hscrollBar.Value, r.Top + headerBuffer + 2, (last + iColPlus1Width /* BMS 2003-05-24 columns[j+1].Width */ > r.Width - 6 ? r.Width - 6 : iColPlus1Width /* BMS 2003-05-24 columns[j+1].Width */- 6), r.Height - 5)); if (node.SubItems[j].ItemControl != null) { Control c = node.SubItems[j].ItemControl; c.Location = new Point(r.Left + last + 4 - hscrollBar.Value, r.Top + (itemheight * totalRend) + headerBuffer + 4); c.ClientSize = new Size(iColPlus1Width /* BMS 2003-05-24 columns[j+1].Width */- 6, itemheight - 4); c.Parent = this; } else { string sp = ""; if (columns[j + 1].TextAlign == HorizontalAlignment.Left) { if (node.Selected && isFocused) g.DrawString(TruncatedString(node.SubItems[j].Text, iColPlus1Width /* BMS 2003-05-24 columns[j+1].Width */, 9, g), this.Font, SystemBrushes.HighlightText, (float)(last + 6 - hscrollBar.Value), (float)(r.Top + (itemheight * totalRend) + headerBuffer + 4)); else g.DrawString(TruncatedString(node.SubItems[j].Text, iColPlus1Width /* BMS 2003-05-24 columns[j+1].Width */, 9, g), this.Font, (node.UseItemStyleForSubItems ? new SolidBrush(node.ForeColor) : SystemBrushes.WindowText), (float)(last + 6 - hscrollBar.Value), (float)(r.Top + (itemheight * totalRend) + headerBuffer + 4)); } else if (columns[j + 1].TextAlign == HorizontalAlignment.Right) { sp = TruncatedString(node.SubItems[j].Text, iColPlus1Width /* BMS 2003-05-24 columns[j+1].Width */, 9, g); if (node.Selected && isFocused) g.DrawString(sp, this.Font, SystemBrushes.HighlightText, (float)(last + iColPlus1Width /* BMS 2003-05-24 columns[j+1].Width */- Helpers.StringTools.MeasureDisplayStringWidth(g, sp, this.Font) - 4 - hscrollBar.Value), (float)(r.Top + (itemheight * totalRend) + headerBuffer + 4)); else g.DrawString(sp, this.Font, (node.UseItemStyleForSubItems ? new SolidBrush(node.ForeColor) : SystemBrushes.WindowText), (float)(last + iColPlus1Width /* BMS 2003-05-24 columns[j+1].Width */- Helpers.StringTools.MeasureDisplayStringWidth(g, sp, this.Font) - 4 - hscrollBar.Value), (float)(r.Top + (itemheight * totalRend) + headerBuffer + 4)); } else { sp = TruncatedString(node.SubItems[j].Text, iColPlus1Width /* BMS 2003-05-24 columns[j+1].Width */, 9, g); if (node.Selected && isFocused) g.DrawString(sp, this.Font, SystemBrushes.HighlightText, (float)(last + (iColPlus1Width /* BMS 2003-05-24 columns[j+1].Width *// 2) - (Helpers.StringTools.MeasureDisplayStringWidth(g, sp, this.Font) / 2) - hscrollBar.Value), (float)(r.Top + (itemheight * totalRend) + headerBuffer + 4)); else g.DrawString(sp, this.Font, (node.UseItemStyleForSubItems ? new SolidBrush(node.ForeColor) : SystemBrushes.WindowText), (float)(last + (iColPlus1Width /* BMS 2003-05-24 columns[j+1].Width *// 2) - (Helpers.StringTools.MeasureDisplayStringWidth(g, sp, this.Font) / 2) - hscrollBar.Value), (float)(r.Top + (itemheight * totalRend) + headerBuffer + 4)); } } } } } } }
/// <summary> /// Gets the prior visible node. /// </summary> /// <param name="cCurNode"></param> /// <returns>Returns TRUE if already on the first node</returns> protected bool GetPriorNode(ref TreeListNode cCurNode) { if (cCurNode == null) return true; if (cCurNode.PreviousSibling() == null && cCurNode.ParentNode() != null) { TreeListNode t = (TreeListNode)cCurNode.ParentNode(); if (t.ParentNode() != null) // never select virtualParent node { cCurNode = (TreeListNode)cCurNode.ParentNode(); return false; } } else if (cCurNode.PreviousSibling() != null) { TreeListNode t = (TreeListNode)cCurNode.PreviousSibling(); if (t.Children > 0 && t.IsExpanded) { do { t = (TreeListNode)t.LastChild(); if (!t.IsExpanded | t.Nodes.Count == 0) { cCurNode = t; return false; } } while (t.Children > 0 && t.IsExpanded); } else { cCurNode = (TreeListNode)cCurNode.PreviousSibling(); return false; } } return true; }