TreeNode Выбранный BackColor, в то время как TreeView не сфокусирован
Есть ли простой способ, чтобы выбранный TreeNode сохранил свой SystemColors.Highlight BackColor, пока TreeView не имеет фокуса? Поскольку даже если для HideSelection установлено значение false, выбранный BackColor практически невозможно увидеть.
Выбранный TreeNode, в то время как TreeView имеет фокус:
Выбранный TreeNode, в то время как TreeView не имеет фокуса:
Заранее спасибо.
РЕДАКТИРОВАТЬ: я знаю, что я мог бы установить DrawMode на OwnerDrawAll, а затем добавить пользовательское событие DrawNode. Я пытался сделать это ранее, проблема у меня в том, что я не знаю, как правильно нарисовать соответствующий ImageKey TreeNode.
8 ответов
Решение, работает как шарм:
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;
}
}
Если сохранить SystemColors.Highlight
цвет фона - это все, что вам нужно, тогда вам не нужно устанавливать TreeView
"s DrawMode
собственность на TreeViewDrawMode.OwnerDrawAll
, Установка его в TreeViewDrawMode.OwnerDrawText
должно быть достаточно, поэтому вам не нужно беспокоиться о рисовании TreeNode
соответствует ImageKey
,
Установить
TreeView.DrawMode
вTreeViewDrawMode.OwnerDrawText
:treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
Установить
Treview.HideSelection
вfalse
, так что состояния узла будут сохранены как выбранные:treeView.HideSelection= false;
добавлять
DrawNode
обработчик событий для рисования фона с помощьюSystemColors.Highlight
цвет: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; } }
Я использую это решение, и оно работает лучше
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;
}
}
РЕДАКТИРОВАТЬ
Основываясь на этой документации,
По умолчанию это Color.Empty
Итак, в treeView1_Enter
лучше установить цвет так
treeView1.SelectedNode.BackColor = Color.Empty;
treeView1.SelectedNode.ForeColor = Color.Empty;
Предыдущий ответ
treeView1.SelectedNode.BackColor = treeView1.BackColor;
treeView1.SelectedNode.ForeColor = treeView1.ForeColor;
Если вам просто нужно выделить выбранный узел, когда вид дерева выходит из фокуса, просто используйте treeView.HideSelection = false;
На самом деле по умолчанию выбранный узел подсвечивается, но не отображается, поэтому нам просто нужно присвоить свойству HideSelection значение false.
Нашел это отличное решение здесь (MSDN)
Работал отлично для меня, надеюсь, это поможет кому-то еще.
- Добавьте новый класс (файл с именем MyTreeView.cs) в ваш проект и вставьте код, показанный ниже.
- Компиляция.
- Удалите новый элемент управления "MyTreeView" из верхней части панели инструментов на форму.
Вы также можете настроить его, если знаете, что делаете
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);
}
}
}
Это поведение по умолчанию для дерева. Все, что вам нужно сделать, чтобы изменить его, это переопределить drawnode. Есть еще один ответ о переполнении стека, который объясняет это лучше, чем я мог бы здесь.
Как изменить цвет фона выбранного узла в TreeView, используя TreeViewDrawMode.OwnerDrawAll?
Следующий код работает даже с программно выбранными узлами.
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;
}
Этот вариант ответа IronGeeks работает для меня и работает с 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
Основное отличие состоит в том, что пользовательский рисунок выполняется, даже если TreeView
сосредоточен. А также DrawString()
используется вместо DrawText()
,