ejemplos c# winforms treeview custom-draw

c# - ejemplos - treenode java



TreeNode seleccionó BackColor mientras que TreeView no estaba enfocado (8)

¿Hay una manera fácil de hacer que un TreeNode seleccionado retenga sus colores del sistema? Porque incluso con HideSelection configurado en falso, el BackColor seleccionado es casi imposible de ver.

TreeNode seleccionado, mientras que TreeView tiene el foco:

TreeNode seleccionado, mientras que TreeView no tiene foco:

Gracias por adelantado.

EDITAR: Soy consciente de que podría establecer DrawMode en OwnerDrawAll y luego agregar un evento DrawNode personalizado. Intenté esto anteriormente, el problema que tengo es que no sé cómo dibujar adecuadamente el ImageKey correspondiente del TreeNode.


El siguiente código funciona incluso con nodos seleccionados mediante programación.

public TreeNode m_previousSelectedNode = null; private void m_treeView_AfterSelect(object sender, TreeViewEventArgs e) { if (m_previousSelectedNode != null) { m_previousSelectedNode.BackColor = m_treeView.BackColor; m_previousSelectedNode.ForeColor = m_treeView.ForeColor; } e.Node.BackColor = SystemColors.Highlight; e.Node.ForeColor = Color.White; m_previousSelectedNode = m_treeView.SelectedNode; }


Encontré esta gran solución aquí (MSDN)

Funcionó muy bien para mí, espero que ayude a alguien más.

  1. Agregue una nueva clase (archivo llamado MyTreeView.cs) a su proyecto y pegue el código que se muestra a continuación.
  2. Compilar.
  3. Suelte el nuevo control llamado "MyTreeView" desde la parte superior de la caja de herramientas en su formulario.

Puedes personalizarlo también, si sabes lo que estás haciendo

using System; using System.Drawing; using System.Windows.Forms; class MyTreeView : TreeView { public MyTreeView() { this.DrawMode = TreeViewDrawMode.OwnerDrawText; } protected override void OnDrawNode(DrawTreeNodeEventArgs e) { TreeNodeStates state = e.State; Font font = e.Node.NodeFont ?? e.Node.TreeView.Font; Color fore = e.Node.ForeColor; if (fore == Color.Empty) fore = e.Node.TreeView.ForeColor; if (e.Node == e.Node.TreeView.SelectedNode) { fore = SystemColors.HighlightText; e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds); ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, fore, SystemColors.Highlight); TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, fore, TextFormatFlags.GlyphOverhangPadding); } else { e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds); TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, fore, TextFormatFlags.GlyphOverhangPadding); } } }


Esta variante de la respuesta de IronGeeks funciona para mí y funciona con Bold Nodes :

Private Sub TreeView1_DrawNode(sender As Object, e As DrawTreeNodeEventArgs) Handles trvIdent.DrawNode Dim treeView = e.Node.TreeView Dim selected = (e.Node Is treeView.SelectedNode) Dim unfocused = Not treeView.Focused Dim font = If(e.Node.NodeFont IsNot Nothing, e.Node.NodeFont, treeView.Font) Dim textSize = e.Graphics.MeasureString(e.Node.Text, font) Dim bounds = New Rectangle(e.Bounds.X, e.Bounds.Y, Convert.ToInt32(textSize.Width), Math.Max(Convert.ToInt32(textSize.Height), e.Bounds.Height)) e.DrawDefault = False If selected Then e.Graphics.FillRectangle(SystemBrushes.Highlight, bounds) e.Graphics.DrawString(e.Node.Text, font, SystemBrushes.HighlightText, bounds.Location) Else e.Graphics.FillRectangle(SystemBrushes.Window, bounds) e.Graphics.DrawString(e.Node.Text, font, SystemBrushes.WindowText, bounds.Location) End If ''e.Graphics.DrawRectangle(Pens.Magenta, bounds) End Sub

La principal diferencia es que el dibujo personalizado se realiza incluso si el TreeView está enfocado. Y DrawString() se utiliza en lugar de DrawText() .



La solución, funciona a la perfección:

public TreeNode previousSelectedNode = null; private void treeView1_Validating(object sender, System.ComponentModel.CancelEventArgs e) { treeView1.SelectedNode.BackColor = SystemColors.Highlight; treeView1.SelectedNode.ForeColor = Color.White; previousSelectedNode = treeView1.SelectedNode; } private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) { if(previousSelectedNode != null) { previousSelectedNode.BackColor = treeView1.BackColor; previousSelectedNode.ForeColor = treeView1.ForeColor; } }


Si lo único que desea es conservar el color de fondo de los colores de la SystemColors.Highlight , entonces no necesita establecer la propiedad DrawMode de TreeViewDrawMode.OwnerDrawAll en TreeViewDrawMode.OwnerDrawAll . Establecerlo en TreeViewDrawMode.OwnerDrawText debería ser suficiente, por lo que no debe preocuparse por dibujar la TreeNode correspondiente del ImageKey .

  1. Establezca TreeView.DrawMode en TreeViewDrawMode.OwnerDrawText :

    treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;

  2. Establezca Treview.HideSelection en false , para que los estados del nodo se mantengan como seleccionados:

    treeView.HideSelection= false;

  3. Agregue el DrawNode eventos DrawNode para dibujar el fondo usando SystemColors.Highlight color:

    private void treeView_DrawNode(object sender, DrawTreeNodeEventArgs e) { if (e.Node == null) return; // if treeview''s HideSelection property is "True", // this will always returns "False" on unfocused treeview var selected = (e.State & TreeNodeStates.Selected) == TreeNodeStates.Selected; var unfocused = !e.Node.TreeView.Focused; // we need to do owner drawing only on a selected node // and when the treeview is unfocused, else let the OS do it for us if (selected && unfocused) { var font = e.Node.NodeFont ?? e.Node.TreeView.Font; e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds); TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, SystemColors.HighlightText, TextFormatFlags.GlyphOverhangPadding); } else { e.DrawDefault = true; } }


Yo uso esta solución, y funciona mejor.

private void treeView1_Enter(object sender, EventArgs e) { if (treeView1.SelectedNode != null) { treeView1.SelectedNode.BackColor = Color.Empty; treeView1.SelectedNode.ForeColor = Color.Empty; } } private void treeView1_Leave(object sender, EventArgs e) { if (treeView1.SelectedNode != null) { treeView1.SelectedNode.BackColor = SystemColors.Highlight; treeView1.SelectedNode.ForeColor = Color.White; } }

EDITAR

Basado en this documentación,

El valor predeterminado es Color.Empty

Por lo tanto, en treeView1_Enter es mejor configurar el color como este

treeView1.SelectedNode.BackColor = Color.Empty; treeView1.SelectedNode.ForeColor = Color.Empty;

Respuesta anterior

treeView1.SelectedNode.BackColor = treeView1.BackColor; treeView1.SelectedNode.ForeColor = treeView1.ForeColor;


si solo necesita resaltar el nodo seleccionado cuando la vista de árbol se desenfoca, simplemente use treeView.HideSelection = false;

En realidad, de forma predeterminada, el nodo seleccionado está resaltado pero no es visible, por lo que solo tenemos que hacer que la propiedad HideSelection sea falsa.