Пример #1
0
        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            if (!paddingok)
            {
                PrepareDraw();
                cellStyle.Padding = Style.Padding;
            }

            DataGridViewRow xrow = this.DataGridView.Rows[rowIndex];

            if (!(xrow is TreeGridRow))
            {
                return;
            }
            TreeGridRow node = (TreeGridRow)xrow;

            if (node == null)
            {
                return;
            }

            Image image = node.Image;

            if (this._imageHeight == 0 && image != null)
            {
                this.UpdateStyle();
            }

            // paint the cell normally
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);

            // TODO: Indent width needs to take image size into account
            Rectangle glyphRect = new Rectangle(cellBounds.X + this.GlyphMargin, cellBounds.Y, INDENT_WIDTH, cellBounds.Height - 1);
            int       glyphHalf = glyphRect.Width / 2;

            //TODO: This painting code needs to be rehashed to be cleaner
            int level = this.Level;

            //TODO: Rehash this to take different Imagelayouts into account. This will speed up drawing
            //		for images of the same size (ImageLayout.None)
            if (image != null)
            {
                Point pp;
                if (_imageHeight > cellBounds.Height)
                {
                    pp = new Point(glyphRect.X + this.glyphWidth, cellBounds.Y + _imageHeightOffset);
                }
                else
                {
                    pp = new Point(glyphRect.X + this.glyphWidth, (cellBounds.Height / 2 - _imageHeight / 2) + cellBounds.Y);
                }

                // Graphics container to push/pop changes. This enables us to set clipping when painting
                // the cell's image -- keeps it from bleeding outsize of cells.
                System.Drawing.Drawing2D.GraphicsContainer gc = graphics.BeginContainer();
                {
                    graphics.SetClip(cellBounds);
                    graphics.DrawImageUnscaled(image, pp);
                }
                graphics.EndContainer(gc);
            }

            // Paint tree lines
            if (((TreeGridAdvanced)(DataGridView)).ShowLines)
            {
                using (Pen linePen = new Pen(SystemBrushes.ControlDark, 1.0f))
                {
                    linePen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                    bool isLastSibling  = node.IsLastSibling;
                    bool isFirstSibling = node.IsFirstSibling;
                    if (node.Level == 1)
                    {
                        // the Root nodes display their lines differently
                        if (isFirstSibling && isLastSibling)
                        {
                            // only node, both first and last. Just draw horizontal line
                            graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
                        }
                        else if (isLastSibling)
                        {
                            // last sibling doesn't draw the line extended below. Paint horizontal then vertical
                            graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
                            graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2);
                        }
                        else if (isFirstSibling)
                        {
                            // first sibling doesn't draw the line extended above. Paint horizontal then vertical
                            graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
                            graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2, glyphRect.X + 4, cellBounds.Bottom);
                        }
                        else
                        {
                            // normal drawing draws extended from top to bottom. Paint horizontal then vertical
                            graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
                            graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top, glyphRect.X + 4, cellBounds.Bottom);
                        }
                    }
                    else
                    {
                        if (isLastSibling)
                        {
                            // last sibling doesn't draw the line extended below. Paint horizontal then vertical
                            graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
                            graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2);
                        }
                        else
                        {
                            // normal drawing draws extended from top to bottom. Paint horizontal then vertical
                            graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2);
                            graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top, glyphRect.X + 4, cellBounds.Bottom);
                        }

                        // paint lines of previous levels to the root
                        TreeGridRow previousNode   = node.Parent;
                        int         horizontalStop = (glyphRect.X + 4) - INDENT_WIDTH;

                        if (previousNode != null)
                        {
                            while (!previousNode.IsRoot)
                            {
                                if (previousNode.HasChildren && !previousNode.IsLastSibling)
                                {
                                    // paint vertical line
                                    graphics.DrawLine(linePen, horizontalStop, cellBounds.Top, horizontalStop, cellBounds.Bottom);
                                }
                                previousNode   = previousNode.Parent;
                                horizontalStop = horizontalStop - INDENT_WIDTH;
                                if (previousNode == null)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            if (node.HasChildren)
            {
                TreeGridAdvanced _grid = (TreeGridAdvanced)DataGridView;
                // Paint node glyphs
                if (node.Node.Expanded)
                {
                    if (_grid.themesenabled)
                    {
                        try
                        {
                            if (_grid.rOpen == null)
                            {
                                _grid.rOpen        = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);
                                _grid.treeboxwidth = System.Convert.ToInt32(WinFormsGraphics.DPIScale * 10);
                            }
                            _grid.rOpen.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4,
                                                                               _grid.treeboxwidth, _grid.treeboxwidth));

                            /*
                             * Pen npen = Pens.Black;
                             * int recwidth = 8;
                             * int margin = 2;
                             * int leftmargin = -recwidth / 2 - 2;
                             * int topmargin = 0;
                             * Rectangle nrect = new Rectangle(leftmargin + glyphRect.X + glyphRect.Width / 2 - recwidth / 2,
                             *                              topmargin + glyphRect.Y + glyphRect.Height / 2 - recwidth / 2,
                             *                              recwidth,
                             *                              recwidth);
                             * graphics.DrawLine(npen, new Point(nrect.X + margin, nrect.Top + recwidth / 2),
                             *                      new Point(nrect.X + recwidth - margin, nrect.Top + recwidth / 2));*/
                        }
                        catch
                        {
                            _grid.themesenabled = false;
                        }
                    }
                    if (!_grid.themesenabled)
                    {
                        Pen       npen       = Pens.Black;
                        int       recwidth   = 8;
                        int       margin     = 2;
                        int       leftmargin = -recwidth / 2 - 2;
                        int       topmargin  = 0;
                        Rectangle nrect      = new Rectangle(leftmargin + glyphRect.X + glyphRect.Width / 2 - recwidth / 2,
                                                             topmargin + glyphRect.Y + glyphRect.Height / 2 - recwidth / 2,
                                                             recwidth,
                                                             recwidth);
                        using (Brush nbrush = new SolidBrush(cellStyle.BackColor))
                        {
                            graphics.FillRectangle(nbrush, nrect);
                            graphics.DrawRectangle(npen, nrect);
                            graphics.DrawLine(npen, new Point(nrect.X + margin, nrect.Top + recwidth / 2),
                                              new Point(nrect.X + recwidth - margin, nrect.Top + recwidth / 2));
                        }
                    }
                }
                else
                {
                    if (_grid.themesenabled)
                    {
                        try
                        {
                            if (_grid.rClosed == null)
                            {
                                _grid.rClosed      = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed);
                                _grid.treeboxwidth = System.Convert.ToInt32(WinFormsGraphics.DPIScale * 10);
                            }
                            //    node._grid.rClosed = new VisualStyleRenderer("Explorer::TreeView",2,1);
                            _grid.rClosed.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, _grid.treeboxwidth, _grid.treeboxwidth));
                        }
                        catch
                        {
                            _grid.themesenabled = false;
                        }
                    }
                    if (!_grid.themesenabled)
                    {
                        Pen npen       = Pens.Black;
                        int recwidth   = 8;
                        int margin     = 2;
                        int leftmargin = -recwidth / 2 - 2;
                        int topmargin  = 0;
                        using (Brush nbrush = new SolidBrush(cellStyle.BackColor))
                        {
                            Rectangle nrect = new Rectangle(leftmargin + glyphRect.X + glyphRect.Width / 2 - recwidth / 2,
                                                            topmargin + glyphRect.Y + glyphRect.Height / 2 - recwidth / 2,
                                                            recwidth,
                                                            recwidth);
                            graphics.FillRectangle(nbrush, nrect);
                            graphics.DrawRectangle(npen, nrect);
                            graphics.DrawLine(npen, new Point(nrect.X + margin, nrect.Top + recwidth / 2),
                                              new Point(nrect.X + recwidth - margin, nrect.Top + recwidth / 2));
                            graphics.DrawLine(npen, new Point(nrect.X + recwidth / 2, nrect.Top + margin),
                                              new Point(nrect.X + recwidth / 2, nrect.Top + recwidth - margin));
                        }
                    }
                }
            }
        }
Пример #2
0
        // Performance bottleneck
        internal protected virtual void UpdateStyle()
        {
            if (this.RowIndex < 0)
            {
                return;
            }
            if (paddingok)
            {
                return;
            }
            int level = this.Level;

            Size preferredSize;

            // This line consumes lot of memory
            Graphics g = ((TreeGridAdvanced)DataGridView).GetGraphics();

            // Graphics g = ((TreeGridView)this.DataGridView).GetGraphics();

            preferredSize = this.GetPreferredSize(g, this.InheritedStyle, this.RowIndex, new Size(0, 0));
            //preferredSize = new Size(20, 21);

            Image image = ((TreeGridRow)DataGridView.Rows[RowIndex]).Image;

            if (image != null)
            {
                // calculate image size
                _imageWidth  = image.Width + 2;
                _imageHeight = image.Height + 2;
            }
            else
            {
                _imageWidth  = glyphWidth;
                _imageHeight = 0;
            }
            Padding p = new Padding();

            // TODO: Make this cleaner
            if (preferredSize.Height < _imageHeight)
            {
                int leftpad = p.Left + (level * INDENT_WIDTH) + _imageWidth + INDENT_MARGIN;
                // Performance bottleneck changing padding takes lot of time
                TreeGridAdvanced _grid = (TreeGridAdvanced)this.DataGridView;
                if (_grid.paddings_list.IndexOfKey(leftpad) >= 0)
                {
                    this.Style = _grid.paddings_list.Values[leftpad];
                }
                else
                {
                    Padding npad = new Padding(leftpad,
                                               p.Top + (_imageHeight / 2), p.Right, p.Bottom + (_imageHeight / 2));
                    this.Style.Padding = npad;
                    _grid.paddings_list.Add(leftpad, this.Style);
                }
                _imageHeightOffset = 2;// (_imageHeight - preferredSize.Height) / 2;
            }
            else
            {
                int leftpad = p.Left + (level * INDENT_WIDTH) + _imageWidth + INDENT_MARGIN;

                Padding oldpad = this.Style.Padding;

                //                if ((oldpad.Left != npad.Left) || (oldpad.Top != npad.Top) || (oldpad.Right != npad.Right) || (oldpad.Bottom != npad.Bottom))
                if (oldpad.Left != leftpad)
                {
                    // Performance bottleneck changing padding takes lot of time
                    TreeGridAdvanced _grid = (TreeGridAdvanced)this.DataGridView;

                    if (_grid.paddings_list.IndexOfKey(leftpad) >= 0)
                    {
                        this.Style = _grid.paddings_list[leftpad];
                    }
                    else
                    {
                        Padding npad = new Padding(leftpad,
                                                   p.Top, p.Right, p.Bottom);
                        this.Style.Padding = npad;
                        _grid.paddings_list.Add(leftpad, this.Style);
                    }
                }
            }

            calculatedLeftPadding = ((level - 1) * glyphWidth) + _imageWidth + INDENT_MARGIN;
            paddingok             = true;
        }