Added the source code of Aga.Controls (TreeViewAdv for .Net) version 1.7.0.0.
3 using System.Diagnostics;
4 using System.Drawing.Drawing2D;
5 using System.Windows.Forms;
6 using Aga.Controls.Tree.NodeControls;
8 namespace Aga.Controls.Tree
10 public partial class TreeViewAdv
12 public void AutoSizeColumn(TreeColumn column)
14 if (!Columns.Contains(column))
15 throw new ArgumentException("column");
17 DrawContext context = new DrawContext();
18 context.Graphics = Graphics.FromImage(new Bitmap(1, 1));
19 context.Font = this.Font;
21 for (int row = 0; row < RowCount; row++)
23 if (row < RowMap.Count)
26 TreeNodeAdv node = RowMap[row];
27 foreach (NodeControl nc in NodeControls)
29 if (nc.ParentColumn == column)
30 w += nc.GetActualSize(node, _measureContext).Width;
32 res = Math.Max(res, w);
40 private void CreatePens()
46 private void CreateMarkPen()
48 GraphicsPath path = new GraphicsPath();
49 path.AddLines(new Point[] { new Point(0, 0), new Point(1, 1), new Point(-1, 1), new Point(0, 0) });
50 CustomLineCap cap = new CustomLineCap(null, path);
51 cap.WidthScale = 1.0f;
53 _markPen = new Pen(_dragDropMarkColor, _dragDropMarkWidth);
54 _markPen.CustomStartCap = cap;
55 _markPen.CustomEndCap = cap;
58 private void CreateLinePen()
60 _linePen = new Pen(_lineColor);
61 _linePen.DashStyle = DashStyle.Dot;
64 protected override void OnPaint(PaintEventArgs e)
66 BeginPerformanceCount();
67 PerformanceAnalyzer.Start("OnPaint");
69 DrawContext context = new DrawContext();
70 context.Graphics = e.Graphics;
71 context.Font = this.Font;
72 context.Enabled = Enabled;
79 DrawColumnHeaders(e.Graphics);
80 y += ColumnHeaderHeight;
81 if (Columns.Count == 0 || e.ClipRectangle.Height <= y)
85 int firstRowY = _rowLayout.GetRowBounds(FirstVisibleRow).Y;
88 e.Graphics.ResetTransform();
89 e.Graphics.TranslateTransform(-OffsetX, y);
90 Rectangle displayRect = DisplayRectangle;
91 for (int row = FirstVisibleRow; row < RowCount; row++)
93 Rectangle rowRect = _rowLayout.GetRowBounds(row);
94 gridHeight += rowRect.Height;
95 if (rowRect.Y + y > displayRect.Bottom)
98 DrawRow(e, ref context, row, rowRect);
101 if ((GridLineStyle & GridLineStyle.Vertical) == GridLineStyle.Vertical && UseColumns)
102 DrawVerticalGridLines(e.Graphics, firstRowY);
104 if (_dropPosition.Node != null && DragMode && HighlightDropPosition)
105 DrawDropMark(e.Graphics);
107 e.Graphics.ResetTransform();
108 DrawScrollBarsBox(e.Graphics);
110 if (DragMode && _dragBitmap != null)
111 e.Graphics.DrawImage(_dragBitmap, PointToClient(MousePosition));
113 PerformanceAnalyzer.Finish("OnPaint");
114 EndPerformanceCount(e);
117 private void DrawRow(PaintEventArgs e, ref DrawContext context, int row, Rectangle rowRect)
119 TreeNodeAdv node = RowMap[row];
120 context.DrawSelection = DrawSelectionMode.None;
121 context.CurrentEditorOwner = CurrentEditorOwner;
124 if ((_dropPosition.Node == node) && _dropPosition.Position == NodePosition.Inside && HighlightDropPosition)
125 context.DrawSelection = DrawSelectionMode.Active;
129 if (node.IsSelected && Focused)
130 context.DrawSelection = DrawSelectionMode.Active;
131 else if (node.IsSelected && !Focused && !HideSelection)
132 context.DrawSelection = DrawSelectionMode.Inactive;
134 context.DrawFocus = Focused && CurrentNode == node;
136 OnRowDraw(e, node, context, row, rowRect);
140 context.DrawFocus = false;
141 if (context.DrawSelection == DrawSelectionMode.Active || context.DrawSelection == DrawSelectionMode.Inactive)
143 Rectangle focusRect = new Rectangle(OffsetX, rowRect.Y, ClientRectangle.Width, rowRect.Height);
144 if (context.DrawSelection == DrawSelectionMode.Active)
146 e.Graphics.FillRectangle(SystemBrushes.Highlight, focusRect);
147 context.DrawSelection = DrawSelectionMode.FullRowSelect;
151 e.Graphics.FillRectangle(SystemBrushes.InactiveBorder, focusRect);
152 context.DrawSelection = DrawSelectionMode.None;
157 if ((GridLineStyle & GridLineStyle.Horizontal) == GridLineStyle.Horizontal)
158 e.Graphics.DrawLine(SystemPens.InactiveBorder, 0, rowRect.Bottom, e.Graphics.ClipBounds.Right, rowRect.Bottom);
161 DrawLines(e.Graphics, node, rowRect);
163 DrawNode(node, context);
166 private void DrawVerticalGridLines(Graphics gr, int y)
169 foreach (TreeColumn c in Columns)
174 gr.DrawLine(SystemPens.InactiveBorder, x - 1, y, x - 1, gr.ClipBounds.Bottom);
179 private void DrawColumnHeaders(Graphics gr)
181 PerformanceAnalyzer.Start("DrawColumnHeaders");
182 ReorderColumnState reorder = Input as ReorderColumnState;
184 TreeColumn.DrawBackground(gr, new Rectangle(0, 0, ClientRectangle.Width + 2, ColumnHeaderHeight - 1), false, false);
185 gr.TranslateTransform(-OffsetX, 0);
186 foreach (TreeColumn c in Columns)
190 if (x >= OffsetX && x - OffsetX < this.Bounds.Width)// skip invisible columns
192 Rectangle rect = new Rectangle(x, 0, c.Width, ColumnHeaderHeight - 1);
194 bool pressed = ((Input is ClickColumnState || reorder != null) && ((Input as ColumnState).Column == c));
195 c.Draw(gr, rect, Font, pressed, _hotColumn == c);
198 if (reorder != null && reorder.DropColumn == c)
199 TreeColumn.DrawDropMark(gr, rect);
207 if (reorder.DropColumn == null)
208 TreeColumn.DrawDropMark(gr, new Rectangle(x, 0, 0, ColumnHeaderHeight));
209 gr.DrawImage(reorder.GhostImage, new Point(reorder.Location.X + + reorder.DragOffset, reorder.Location.Y));
211 PerformanceAnalyzer.Finish("DrawColumnHeaders");
214 public void DrawNode(TreeNodeAdv node, DrawContext context)
216 foreach (NodeControlInfo item in GetNodeControls(node))
218 if (item.Bounds.Right >= OffsetX && item.Bounds.X - OffsetX < this.Bounds.Width)// skip invisible nodes
220 context.Bounds = item.Bounds;
221 context.Graphics.SetClip(context.Bounds);
222 item.Control.Draw(node, context);
223 context.Graphics.ResetClip();
228 private void DrawScrollBarsBox(Graphics gr)
230 Rectangle r1 = DisplayRectangle;
231 Rectangle r2 = ClientRectangle;
232 gr.FillRectangle(SystemBrushes.Control,
233 new Rectangle(r1.Right, r1.Bottom, r2.Width - r1.Width, r2.Height - r1.Height));
236 private void DrawDropMark(Graphics gr)
238 if (_dropPosition.Position == NodePosition.Inside)
241 Rectangle rect = GetNodeBounds(_dropPosition.Node);
242 int right = DisplayRectangle.Right - LeftMargin + OffsetX;
244 if (_dropPosition.Position == NodePosition.After)
246 gr.DrawLine(_markPen, rect.X, y, right, y);
249 private void DrawLines(Graphics gr, TreeNodeAdv node, Rectangle rowRect)
251 if (UseColumns && Columns.Count > 0)
252 gr.SetClip(new Rectangle(0, rowRect.Y, Columns[0].Width, rowRect.Bottom));
254 TreeNodeAdv curNode = node;
255 while (curNode != _root && curNode != null)
257 int level = curNode.Level;
258 int x = (level - 1) * _indent + NodePlusMinus.ImageSize / 2 + LeftMargin;
259 int width = NodePlusMinus.Width - NodePlusMinus.ImageSize / 2;
261 int y2 = y + rowRect.Height;
265 int midy = y + rowRect.Height / 2;
266 gr.DrawLine(_linePen, x, midy, x + width, midy);
267 if (curNode.NextNode == null)
268 y2 = y + rowRect.Height / 2;
272 y = rowRect.Height / 2;
273 if (curNode.NextNode != null || curNode == node)
274 gr.DrawLine(_linePen, x, y, x, y2);
276 curNode = curNode.Parent;
284 private double _totalTime;
285 private int _paintCount;
287 [Conditional("PERF_TEST")]
288 private void BeginPerformanceCount()
294 [Conditional("PERF_TEST")]
295 private void EndPerformanceCount(PaintEventArgs e)
297 double time = TimeCounter.Finish();
299 string debugText = string.Format("FPS {0:0.0}; Avg. FPS {1:0.0}",
300 1 / time, 1 / (_totalTime / _paintCount));
301 e.Graphics.FillRectangle(Brushes.White, new Rectangle(DisplayRectangle.Width - 150, DisplayRectangle.Height - 20, 150, 20));
302 e.Graphics.DrawString(debugText, Control.DefaultFont, Brushes.Gray,
303 new PointF(DisplayRectangle.Width - 150, DisplayRectangle.Height - 20));