MoonKnight
MoonKnight

Reputation: 23833

Dynamically Changing Features of an Overridden TreeView Class

I am overriding a TreeView so that I can highlight the nodes using better colors. As part of the applications options I want to enable the user to change the TreeView's font and the font color when both selected and deselected. The code is below:

class MyTreeView : TreeView
{
    // Create a Font object for the node tags and HotTracking.
    private Font hotFont;
    private Font tagFont = new Font("Helvetica", Convert.ToSingle(8.0), FontStyle.Bold);

    #region Accessors.
    public Font hotTrackFont
    {
        get { return this.hotFont; }
        set { this.hotFont = value; }
    }

    //public string unFocusedColor
    //{
    //   get { return this.strDeselectedColor; }
    //   set { this.strDeselectedColor = value; }
    //}

    //public string focusedColor
    //{
    //   get { return this.strSelectedColor; }
    //   set { this.strSelectedColor = value; }
    //}
    #endregion

    public MyTreeView()
    {
        this.HotTracking = true;
        this.DrawMode = TreeViewDrawMode.OwnerDrawText;
        hotFont = new Font(this.Font.FontFamily, this.Font.Size, FontStyle.Underline);
    }

    // Override the drawMode of TreeView.
    protected override void OnDrawNode(DrawTreeNodeEventArgs e)
    {
        TreeNodeStates treeState = e.State;
        Font treeFont = e.Node.NodeFont ?? e.Node.TreeView.Font;

        // Colors.
        Color foreColor = e.Node.ForeColor;

        // Like with the hotFont I want to be able to change these dynamically...
        string strDeselectedColor = @"#6B6E77", strSelectedColor = @"#94C7FC";
        Color selectedColor = System.Drawing.ColorTranslator.FromHtml(strSelectedColor);
        Color deselectedColor = System.Drawing.ColorTranslator.FromHtml(strDeselectedColor);

        // New brush.
        SolidBrush selectedTreeBrush = new SolidBrush(selectedColor);
        SolidBrush deselectedTreeBrush = new SolidBrush(deselectedColor);

        // Set default font color.
        if (foreColor == Color.Empty)
            foreColor = e.Node.TreeView.ForeColor;

        // Draw bounding box and fill.
        if (e.Node == e.Node.TreeView.SelectedNode)
        {
            // Use appropriate brush depending on if the tree has focus.
            if (this.Focused)
            {
                foreColor = SystemColors.HighlightText;
                e.Graphics.FillRectangle(selectedTreeBrush, e.Bounds);
                ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, SystemColors.Highlight);
                TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds,
                                             foreColor, TextFormatFlags.GlyphOverhangPadding);
            }
            else
            {
                foreColor = SystemColors.HighlightText;
                e.Graphics.FillRectangle(deselectedTreeBrush, e.Bounds);
                ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, SystemColors.Highlight);
                TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds,
                                             foreColor, TextFormatFlags.GlyphOverhangPadding);
            }
        }
        else
        {
            if ((e.State & TreeNodeStates.Hot) == TreeNodeStates.Hot)
            {
                e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
                TextRenderer.DrawText(e.Graphics, e.Node.Text, hotFont, e.Bounds,
                                             System.Drawing.Color.Black, TextFormatFlags.GlyphOverhangPadding);
            }
            else
            {
                e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
                TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds,
                                             foreColor, TextFormatFlags.GlyphOverhangPadding);
            }
        }
    }
}

As you can see I am currently changing the Font hotFont using an accessor to the class which seems to work. However, when I try to edit the colors of the focused/unfocused node, VS2010 crashes! What is it that is causing this behaviour exactly and how can I achieve what I want?

Upvotes: 2

Views: 928

Answers (1)

LarsTech
LarsTech

Reputation: 81620

The posted code does not recreate the error when I enabled those commented out properties and added the variables to the control's scope.

A couple of notes though:

Instead of string properties, I would use an actual color:

private Color _UnfocusedColor = ColorTranslator.FromHtml(@"#94C7FC");
private Color _FocusedColor = ColorTranslator.FromHtml(@"#6B6E77");

public Color UnfocusedColor
{
   get { return _UnfocusedColor; }
   set { _UnfocusedColor = value; }
}

public Color FocusedColor
{
  get { return _FocusedColor; }
  set { _FocusedColor = value; }
}

Also, make sure to dispose of your drawing objects, such as the SolidBrush objects, or wrap them up in a Using(...){} block.

Upvotes: 1

Related Questions