Pregunta

Estoy intentando añadir algunas más iconos a elementos de un control System.Windows.Forms.TreeView estándar.

Mi plan era sólo para cambiar el área de la etiqueta del control de vista de árbol, pero muestra un comportamiento extraño. Si hago clic en un nodo para seleccionarlo, cuando el botón del ratón se presiona el fondo es dibujar correctamente con el color de resaltado. Sin embargo, el texto es el color equivocado no seleccionada hasta que suelte el botón del ratón. Es como si e.State contiene un estado incorrecto entre la pulsación del botón del ratón y puesto en libertad.

Esto es lo que estoy haciendo: Yo INIT con this.DrawMode = TreeViewDrawMode.OwnerDrawText y luego registrar mi controlador de eventos con this.DrawNode += LayoutTreeView_DrawNode. Aquí está el controlador:

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);
}

Si fijo el manejador de su caso por defecto ...

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

... pasa lo mismo, lo cual es extraño ya que las ventanas que realmente está dibujando ahora. Este comportamiento es en Windows XP con .Net 3.5.

¿Hay alguna manera de evitar este comportamiento extraño?

¿Fue útil?

Solución

Cambiar

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

a

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

Esto funcionó en Vista x64 y VS 2008 con .Net 3.5. Déjame saber si funciona para ti.

Lo que observé cuando viendo el comportamiento de ventanas por defecto era que el texto y poner de relieve que no se elaboraron hasta que se selecciona el nodo y tenía foco. Lo que he comprobado para la condición centrada con el fin de cambiar el color del texto. Sin embargo, esto no imita con precisión el comportamiento Viudas, donde los nuevos colores no se usan hasta que se suelte el ratón. Al parecer, el punto cuando se opte por elaborar los azules cambios de estado culminante cuando en el modo ownerdrawn frente a las ventanas de dibujo que ..., que la verdad es confuso.

EDITAR Sin embargo, al crear su propia vista de árbol derivado que tiene el control total sobre todo cuando se dibuja.

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);
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top