Владелец TreeView рисует глюк при выборе

Я пытаюсь добавить еще несколько значков к элементам стандартного элемента управления System.Windows.Forms.TreeView.

Мой план состоял в том, чтобы изменить только область метки элемента управления treeview, но это демонстрирует странное поведение. Если я щелкаю узел, чтобы выбрать его, при нажатии кнопки мыши фон рисуется правильно с цветом подсветки. Тем не менее, текст неправильный невыбранный цвет, пока я не отпущу кнопку мыши. Это как если бы e.State содержит неверное состояние между нажатием и отпусканием кнопки мыши.

Вот что я делаю: я начинаю с this.DrawMode = TreeViewDrawMode.OwnerDrawText а затем зарегистрировать мой обработчик событий с this.DrawNode += LayoutTreeView_DrawNode, Вот обработчик:

void LayoutTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{

    Color color = (e.State & TreeNodeStates.Selected) != 0 ?
        SystemColors.HighlightText : SystemColors.WindowText;

    TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.SingleLine |
       TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis;

    TextRenderer.DrawText(e.Graphics, e.Node.Text, Font, e.Bounds, color, flags);
}

Если я установлю обработчик в его регистр по умолчанию...

void LayoutTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
    e.DefaultDraw = true;
}

... происходит то же самое, что странно, так как окна фактически рисуют это сейчас. Такое поведение в Windows XP с.Net 3.5.

Есть ли способ обойти это странное поведение?

1 ответ

Решение

+ Изменить

Color color = (e.State & TreeNodeStates.Selected) != 0 ?
    SystemColors.HighlightText : SystemColors.WindowText;

в

Color color = (e.State & TreeNodeStates.Focused) != 0 ?
    SystemColors.HighlightText : SystemColors.WindowText;

Это работало на Vista x64 и VS 2008 с.Net 3.5. Дайте мне знать, если это работает для вас.

Когда я наблюдал за поведением окон по умолчанию, я заметил, что текст и подсветка не отображались до тех пор, пока узел не был выбран и не имел фокусировки. Поэтому я проверил фокусное условие, чтобы изменить цвет текста. Однако это точно не имитирует поведение вдов, когда новые цвета не используются до тех пор, пока мышь не будет отпущена. Появляется точка, когда он выбирает рисовать изменения статуса синей подсветки, когда в режиме владельца нарисован, а не рисовать окна... Что, по общему признанию, сбивает с толку.

РЕДАКТИРОВАТЬ Однако, когда вы создаете свое собственное производное древовидное представление, вы полностью контролируете, когда все отрисовывается.

public class MyTreeView : TreeView
{
    bool isLeftMouseDown = false;
    bool isRightMouseDown = false;
    public MyTreeView()
    {
        DrawMode = TreeViewDrawMode.OwnerDrawText;
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        TrackMouseButtons(e);
        base.OnMouseDown(e);
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        TrackMouseButtons(e);
        base.OnMouseUp(e);
    }
    protected override void OnMouseMove(MouseEventArgs e)
    {
        TrackMouseButtons(e);
        base.OnMouseMove(e);
    }

    private void TrackMouseButtons(MouseEventArgs e)
    {
        isLeftMouseDown = e.Button == MouseButtons.Left;
        isRightMouseDown = e.Button == MouseButtons.Right;
    }

    protected override void OnDrawNode(DrawTreeNodeEventArgs e)
    {
        // don't call the base or it will goof up your display!
        // capture the selected/focused states
        bool isFocused = (e.State & TreeNodeStates.Focused) != 0;
        bool isSelected = (e.State & TreeNodeStates.Selected) != 0;
        // set up default colors.
        Color color = SystemColors.WindowText;
        Color backColor = BackColor;

        if (isFocused && isRightMouseDown)
        {
            // right clicking on a 
            color = SystemColors.HighlightText;
            backColor = SystemColors.Highlight;
        }
        else if (isSelected && !isRightMouseDown)
        {
            // if the node is selected and we're not right clicking on another node.
            color = SystemColors.HighlightText;
            backColor = SystemColors.Highlight;
        }

        using (Brush sb = new SolidBrush(backColor))
            e.Graphics.FillRectangle(sb,e.Bounds);

        TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.SingleLine |
           TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis;

        TextRenderer.DrawText(e.Graphics, e.Node.Text, Font, e.Bounds, color, backColor, flags);
    }
}
Другие вопросы по тегам