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.
- Agregue una nueva clase (archivo llamado MyTreeView.cs) a su proyecto y pegue el código que se muestra a continuación.
- Compilar.
- 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()
.
Este es el comportamiento predeterminado para la vista de árbol. Todo lo que necesita hacer para cambiarlo es anular drawnode. Hay otra respuesta de desbordamiento de pila que lo explica mejor de lo que podría aquí.
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
.
Establezca
TreeView.DrawMode
enTreeViewDrawMode.OwnerDrawText
:treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
Establezca
Treview.HideSelection
enfalse
, para que los estados del nodo se mantengan como seleccionados:treeView.HideSelection= false;
Agregue el
DrawNode
eventosDrawNode
para dibujar el fondo usandoSystemColors.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.