/// <summary> /// Draw an expand/collapse box for the given node using provided centre point. /// </summary> /// <param name="tc">Reference to owning TreeControl.</param> /// <param name="n">Reference to Node instance.</param> /// <param name="g">Reference to Graphics instance to draw into.</param> /// <param name="x">X centre of box.</param> /// <param name="y">Y centre of box.</param> public virtual void DrawExpandCollapseBox(TreeControl tc, Node n, Graphics g, int x, int y) { bool hasChildren = (n.Nodes.VisibleCount > 0); // Do we need to draw a box for this child node? if (tc.BoxShownAlways || hasChildren) { // Create rectangle at centre of box position Rectangle box = new Rectangle(x, y, 0, 0); // If we theme information and the boxes need drawing themed if (tc.IsControlThemed && (tc.BoxDrawStyle == DrawStyle.Themed)) { // Themes cannot support the drawing of an empty expand/collapse box if (hasChildren) { // Find how far to expand left and up int halfV = tc.GlyphThemeSize.Height / 2; int halfH = tc.GlyphThemeSize.Width / 2; // Move box so that centre of box is centred box.Y -= halfV; box.X -= halfH; // Expand it to required size box.Size = tc.GlyphThemeSize; // Ask the tree to draw the themed box in required state tc.DrawThemedBox(g, box, n.IsExpanded); } } else { // Should we draw in the gradient style? bool gradient = (tc.BoxDrawStyle == DrawStyle.Gradient); // Find how far to expand left and up int half = tc.BoxLength / 2; // Expand it to required size box.X -= half; box.Y -= half; box.Width = tc.BoxLength - 1; box.Height = tc.BoxLength - 1; if (gradient) { // Modify box very slightly to make gradient look better Rectangle boxCopy = box; boxCopy.Inflate(1, 1); // Create graduated brush using inside color and box size using (Brush brush = new LinearGradientBrush(boxCopy, tc.BoxInsideColor, tc.BackColor, 225)) { // Fill inside with required brush first g.FillRectangle(brush, box); } // Draw the border as all except the four corner pixels using (Pen pen = new Pen(tc.BoxBorderColor, 1), lightPen = new Pen(ControlPaint.Light(tc.BoxBorderColor, 1))) { g.DrawLine(pen, box.Left + 1, box.Bottom, box.Right - 1, box.Bottom); g.DrawLine(pen, box.Right, box.Top + 1, box.Right, box.Bottom - 1); g.DrawLine(lightPen, box.Left + 1, box.Top, box.Right - 1, box.Top); g.DrawLine(lightPen, box.Left, box.Top + 1, box.Left, box.Bottom - 1); } } else { // Fill inside with required brush first g.FillRectangle(tc.GetCacheBoxInsideBrush(), box); // Draw border in required color around box g.DrawRectangle(tc.GetCacheBoxBorderPen(), box); } // Only draw a plus/minus sign if node has children if (hasChildren) { // Cannot draw a sign if the box is too small to show it if (tc.BoxLength >= 7) { Pen boxSignPen = tc.GetCacheBoxSignPen(); // Find length of the line for drawing sign int sign = (tc.BoxLength / 3) - 1; // Always draw the minus part of sign g.DrawLine(boxSignPen, box.X + half, box.Y + half, box.X + half - sign, box.Y + half); g.DrawLine(boxSignPen, box.X + half, box.Y + half, box.X + half + sign, box.Y + half); // Only draw the line to make it a plus sign, if not expanded if (!n.IsExpanded) { g.DrawLine(boxSignPen, box.X + half, box.Y + half, box.X + half, box.Y + half - sign); g.DrawLine(boxSignPen, box.X + half, box.Y + half, box.X + half, box.Y + half + sign); } } } else { // Otherwise we just draw a dot at the center g.DrawLine(tc.GetCacheBoxSignPen(), new PointF(box.X + half, box.Y + half), new PointF(box.X + half + 0.1f, box.Y + half)); } } } }