Правильный рендеринг переопределенного TreeView - PullRequest
2 голосов
/ 09 января 2012

У меня были проблемы со стандартным Windows Forms TreeView; особенно с цветом, с помощью которого элемент управления по умолчанию используется для визуализации выбранного узла, когда древовидное представление не имело фокусировки. Это был светло-серый, который на некоторых экранах был почти невидим. Впоследствии я создал подкласс TreeView и переопределил событие TreeView OnDrawNode, чтобы покрасить свои узлы, как я хочу. Это работает хорошо, но теперь «HotTracking» (активное выделение, когда мышь находится над данным узлом дерева) перезаписывается моим пользовательским событием OnDrawNode. Я не слишком знаком с классами Graphics и удивляюсь, как я могу изменить свой текущий подкласс, чтобы включить горячее отслеживание? Я знаю, что мог бы использовать e.Graphics.DrawLine(Pen pen, Point p1, Point p2);, но это станет грязным, есть ли более простой способ?

Вот существующий код:

class CustomTreeView : TreeView 
{
    public CustomTreeView() 
    {
        this.DrawMode = TreeViewDrawMode.OwnerDrawText;
    }

    // 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;
        string strDeselectedColor = @"#6B6E77", strSelectedColor = @"#94C7FC"; //@"#1ABEE8"; //@"#2FC0EE"; //@"#3A8FEA";
        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 /*SystemBrushes.Highlight*/, 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 /*SystemBrushes.Highlight*/, 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 
        {
            // This is firing but is being over written, perhaps by the above?
            if ((e.State & TreeNodeStates.Hot) == TreeNodeStates.Hot)
            {
                e.DrawDefault = true;
                e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
                TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, System.Drawing.Color.Blue, TextFormatFlags.GlyphOverhangPadding);
            }
            else
            {
                e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
                TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, foreColor, TextFormatFlags.GlyphOverhangPadding);
           }   
        }
    }

Как всегда, ребята, большое спасибо за ваше время.

Ответы [ 2 ]

5 голосов
/ 09 января 2012

Вам необходимо обратить внимание на e.State в вашем коде. Свойство DrawTreeNodeEventArgs.State сообщает о том, что происходит с узлом, соответственно выберите цвета. Также ознакомьтесь с примером библиотеки MSDN, показанным в документации к TreeNode.DrawNode, для получения рекомендаций.

0 голосов
/ 18 августа 2015

Просто установите HotTracking вашего TreeView в true, и он будет работать, потому что в TreeView узлы, которые он содержит, не имеют самоидентификации как элемента управления, каждый узел рисуется самим TreeView, в то время как узлы просто содержат данныеВот почему у них нет событий, а TreeView выполняет всю работу, поэтому, чтобы установить эти «горячие» статусы

objTreeView.HotTracking = true;

TreeView начнет предоставлять вам статус, и выкод будет работать нормально.

...