Menu

Added support for row colors and +/- Icons

2009-09-07
2013-04-29
  • Matthias Frensel

    Some people want to change the backcolor for the rows. I've added this feature and some more to treeviewadv for one of my projects.

    I post my changes here so everybody who wants to change the plusminusicons, the gridlinecolor, the backcolor for active and inactive highlighted rows and for visible rows can add this code.

    Add this to TreeViewAdv.Properties.cs:
            private Bitmap _minusImage = Resources.minus;
            [Category("Appearance")]
            public Bitmap MinusImage
            {
                get { return _minusImage; }
                set
                {
                    if (value != _minusImage)
                    {
                        _minusImage = value;
                        FullUpdate();
                    }
                }
            }

            private Bitmap _plusImage = Resources.plus;
            [Category("Appearance")]
            public Bitmap PlusImage
            {
                get { return _plusImage; }
                set
                {
                    if (value != _plusImage)
                    {
                        _plusImage = value;
                        FullUpdate();
                    }
                }
            }

            private SolidBrush _highlightRowBackColorBrush = new SolidBrush(SystemColors.InactiveBorder);
            internal SolidBrush HighlightRowBackColorBrush
            {
                get { return _highlightRowBackColorBrush; }
                set { _highlightRowBackColorBrush = value; }
            }

            [Category("Behavior")]
            public Color HighlightRowBackColor
            {
                get { return _highlightRowBackColorBrush.Color; }
                set
                {
                    if (_highlightRowBackColorBrush.Color != value)
                    {
                        _highlightRowBackColorBrush.Color = value;
                        FullUpdate();
                    }
                }
            }
            private SolidBrush _inactiveHighlightrowBackColorBrush = new SolidBrush(SystemColors.InactiveBorder);
            internal SolidBrush InactiveHighlightRowBackColorBrush
            {
                get { return _inactiveHighlightrowBackColorBrush; }
                set { _inactiveHighlightrowBackColorBrush = value; }
            }

            [Category("Behavior")]
            public Color InactiveHighlightRowBackColor
            {
                get { return _inactiveHighlightrowBackColorBrush.Color; }
                set
                {
                    if (_inactiveHighlightrowBackColorBrush.Color != value)
                    {
                        _inactiveHighlightrowBackColorBrush.Color = value;
                        FullUpdate();
                    }
                }
            }

            private SolidBrush _rowBackColorBrush = new SolidBrush(DefaultBackColor);
            internal SolidBrush RowBackColorBrush
            {
                get { return _rowBackColorBrush; }
                set { _rowBackColorBrush = value; }
            }

            [Category("Behavior")]
            public Color RowBackColor
            {
                get { return _rowBackColorBrush.Color; }
                set
                {
                    if (_rowBackColorBrush.Color != value)
                    {
                        _rowBackColorBrush.Color = value;
                        FullUpdate();
                    }
                }
            }

            private Pen _gridLinePen = SystemPens.InactiveBorder;
            internal Pen GridLinePen
            {
                get { return _gridLinePen; }
                set { _gridLinePen = value; }
            }

            [Category("Behavior")]
            public Color GridLineColor
            {
                get { return _gridLinePen.Color; }
                set
                {
                    if (_gridLinePen.Color != value)
                    {
                        _gridLinePen = new Pen(value);
                        FullUpdate();
                    }
                }
            }

    Change in NodePlusMinus.cs:
    public NodePlusMinus():this(Resources.plus,Resources.minus){}

            public NodePlusMinus(Bitmap plus, Bitmap minus)
            {
                _plus = plus;
                _minus = minus;
            }

    Replace DrawVerticalGridLines and DrawRow in TreeViewAdv.Draw.cs with:
    private void DrawRow(PaintEventArgs e, ref DrawContext context, int row, Rectangle rowRect)
            {
                TreeNodeAdv node = RowMap[row];
                context.DrawSelection = DrawSelectionMode.None;
                context.CurrentEditorOwner = _currentEditorOwner;
                if (DragMode)
                {
                    if ((_dropPosition.Node == node) && _dropPosition.Position == NodePosition.Inside && HighlightDropPosition)
                        context.DrawSelection = DrawSelectionMode.Active;
                }
                else
                {
                    if (node.IsSelected && Focused)
                        context.DrawSelection = DrawSelectionMode.Active;
                    else if (node.IsSelected && !Focused && !HideSelection)
                        context.DrawSelection = DrawSelectionMode.Inactive;
                }
                context.DrawFocus = Focused && CurrentNode == node;

                if (FullRowSelect)
                {
                    context.DrawFocus = false;
                    if (context.DrawSelection == DrawSelectionMode.Active || context.DrawSelection == DrawSelectionMode.Inactive)
                    {
                        Rectangle focusRect = new Rectangle(OffsetX, rowRect.Y, ClientRectangle.Width, rowRect.Height);
                        if (context.DrawSelection == DrawSelectionMode.Active)
                        {
                            e.Graphics.FillRectangle(HighlightRowBackColorBrush, focusRect);
                            context.DrawSelection = DrawSelectionMode.FullRowSelect;
                        }
                        else
                        {
                            e.Graphics.FillRectangle(InactiveHighlightRowBackColorBrush, focusRect);
                            context.DrawSelection = DrawSelectionMode.None;
                        }
                    }
                    else
                    {
                        Rectangle backgroundRect = new Rectangle(OffsetX, rowRect.Y, ClientRectangle.Width, rowRect.Height);
                        e.Graphics.FillRectangle(RowBackColorBrush, backgroundRect);
                    }
                }

                if ((GridLineStyle & GridLineStyle.Horizontal) == GridLineStyle.Horizontal)
                    e.Graphics.DrawLine(GridLinePen, 0, rowRect.Bottom, e.Graphics.ClipBounds.Right, rowRect.Bottom);

                if (ShowLines)
                    DrawLines(e.Graphics, node, rowRect);

                DrawNode(node, context);
            }

            private void DrawVerticalGridLines(Graphics gr, int y)
            {
                int x = 0;
                foreach (TreeColumn c in Columns)
                {
                    if (c.IsVisible)
                    {
                        x += c.Width;
                        gr.DrawLine(GridLinePen, x - 1, y, x - 1, gr.ClipBounds.Bottom);
                    }
                }
            }

    And finally replace in TreeViewAdv.cs:
    _plusMinus = new NodePlusMinus();
    with
    _plusMinus = new NodePlusMinus(PlusImage,MinusImage);

    I hope I didn't miss anything.

     
    • Nobody/Anonymous

      The name '_currentEditorOwner' does not exist in the current context

       
    • Nobody/Anonymous

      Thanks for the update!  Using the updated model, how would I go about changing the color of every other row in the tree?

       
    • Matthias Frensel

      _currentEditorOwner is from version 1.6. It's called CurrentEditorOwner in 1.7

      In DrawRow you can get the current node of this row by using TreeNodeAdv node = RowMap[row].
      node.Tag contains an instance of your node class. If you add a brush as property to your node class you can modify DrawRow to set the color for every row independently.

      If you want to change the color of all rows except the selected row, just set RowBackColor.

      I see that I posted the old version from 1.6, I'll try to post the 1.7 version tomorrow.

       
      • Nobody/Anonymous

        Thanks, works great!

         
        • Nobody/Anonymous

          Just a general note to anyone wanting to avoid headaches when coloring the rows:

          FullRowSelect MUST be set to True for the row coloring to have any effect.  This remains to be the case when the tree only has a single column.

           
  • Georg S

    Georg S - 2017-07-16

    Also, should probably also add

    if (_rowBackColorBrush != null) _rowBackColorBrush.Dispose();
    if (_inactiveHighlightrowBackColorBrush != null) _inactiveHighlightrowBackColorBrush.Dispose();
    if (_gridLinePen != null) _gridLinePen.Dispose();
    if (_highlightRowBackColorBrush != null) _highlightRowBackColorBrush.Dispose();

    to your class void Dispose(bool disposing) routine
    (I didn't use the +/- minus stuff so may need more for that option)

     

Log in to post a comment.