我遇到标准Windows窗体TreeView的问题;特别是当树视图没有焦点时,默认控件用于渲染所选节点的颜色。这是浅灰色,在某些屏幕上几乎看不见。随后,我已经将TreeView子类化并覆盖了TreeView OnDrawNode
事件,以便按照我的意愿为我的节点着色。这很好用,但现在'HotTracking'(当鼠标在给定树节点上时激活突出显示)被我的自定义OnDrawNode
事件覆盖。我对Graphics
类不太熟悉,并想知道如何修改我当前的子类以包含热跟踪?我知道我可以使用e.Graphics.DrawLine(Pen pen, Point p1, Point p2);
但这会变得混乱,有更简单的方法吗?
以下是现有代码:
class CustomTreeView : TreeView
{
public CustomTreeView()
{
this.DrawMode = TreeViewDrawMode.OwnerDrawText;
}
// Override the drawMode of TreeView.
protected override void OnDrawNode(DrawTreeNodeEventArgs e)
{
TreeNodeStates treeState = e.State;
Font treeFont = e.Node.NodeFont ?? e.Node.TreeView.Font;
// Colors.
Color foreColor = e.Node.ForeColor;
string strDeselectedColor = @"#6B6E77", strSelectedColor = @"#94C7FC"; //@"#1ABEE8"; //@"#2FC0EE"; //@"#3A8FEA";
Color selectedColor = System.Drawing.ColorTranslator.FromHtml(strSelectedColor);
Color deselectedColor = System.Drawing.ColorTranslator.FromHtml(strDeselectedColor);
// New brush.
SolidBrush selectedTreeBrush = new SolidBrush(selectedColor);
SolidBrush deselectedTreeBrush = new SolidBrush(deselectedColor);
// Set default font color.
if (foreColor == Color.Empty)
foreColor = e.Node.TreeView.ForeColor;
// Draw bounding box and fill.
if (e.Node == e.Node.TreeView.SelectedNode)
{
// Use appropriate brush depending on if the tree has focus.
if (this.Focused)
{
foreColor = SystemColors.HighlightText;
e.Graphics.FillRectangle(selectedTreeBrush /*SystemBrushes.Highlight*/, e.Bounds);
ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, SystemColors.Highlight);
TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, foreColor, TextFormatFlags.GlyphOverhangPadding);
}
else
{
foreColor = SystemColors.HighlightText;
e.Graphics.FillRectangle(deselectedTreeBrush /*SystemBrushes.Highlight*/, e.Bounds);
ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, SystemColors.Highlight);
TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, foreColor, TextFormatFlags.GlyphOverhangPadding);
}
}
else
{
// This is firing but is being over written, perhaps by the above?
if ((e.State & TreeNodeStates.Hot) == TreeNodeStates.Hot)
{
e.DrawDefault = true;
e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, System.Drawing.Color.Blue, TextFormatFlags.GlyphOverhangPadding);
}
else
{
e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, foreColor, TextFormatFlags.GlyphOverhangPadding);
}
}
}
像往常一样,非常感谢您的时间。
答案 0 :(得分:5)
您需要注意代码中的e.State。 DrawTreeNodeEventArgs.State属性告诉您节点的运行情况,相应地选择颜色。另请查看TreeNode.DrawNode文档中显示的MSDN库示例以获取指导。
答案 1 :(得分:0)
只需将TreeView的HotTracking设置为true即可,因为在TreeView中,它包含的节点没有自身标识作为控件,每个节点都由TreeView本身绘制,而节点只包含数据,这就是为什么他们没有事件并且TreeView完成整个工作,所以要设置这些热状态
objTreeView.HotTracking = true;
TreeView将开始为您提供状态,您的代码将正常运行。