【问题标题】:Set background color of a TreeNode设置 TreeNode 的背景颜色
【发布时间】:2017-05-16 15:43:42
【问题描述】:

我有一个这样的 TreeView:

System.Windows.Forms.TreeView treeView;
this.treeView = new System.Windows.Forms.TreeView();

treeView.Update();
treeNode = this.treeView.Nodes.Add(yadda1);
treeNode = this.treeView.Nodes.Add(yadda2);
treeNode = this.treeView.Nodes.Add(yadda3);

foreach (TreeNode node in treeView.Nodes)
{
    namedNode = getTreeNodeFromName(documentType, node);
    if (namedNode != null)
    {
        break; // found it
    }
}
treeView.SelectedNode = namedNode;
treeView.SelectedNode.BackColor = Color.Blue;
treeView.Focus();
this.treeView.EndUpdate();

这段代码几乎可以工作。默认情况下,所选节点由背景颜色指示为非常浅的灰色,很难看到。所以我以编程方式将其设置为蓝色,但在用户单击另一个节点之前,背景不会变为蓝色。

之前的问题建议致电treeView.Focus(),但这没有区别。

如何让背景颜色立即变为蓝色?

【问题讨论】:

  • 您正在尝试更改系统的突出显示颜色。为此,您必须自己绘制节点。请参阅 DrawMode 属性和 DrawNode 事件。
  • LarsTech 是正确的,如果您想这样做,您必须回答 DrawNode 事件。这实际上相当简单。这应该让你开始。 msdn.microsoft.com/en-us/library/…
  • 有些液晶显示器无法很好地显示像这样的不饱和颜色。不是我的,我怀疑我会非常感谢一个覆盖它的程序。鉴于这会影响您机器上的每个程序,合理的解决方案是更改系统颜色。
  • @HansPassant:我认为在我的应用程序中更改 TreeView 的颜色只会影响我的应用程序,而不是我机器上的每个程序。对吗?

标签: c# winforms treeview


【解决方案1】:

这是另一种方法。直接继承自 TreeView 类。这只是获得了绘制节点文本部分的基础知识。我仍在处理“线路”部分,但这必须等到我回家。但是,这将使您入门并显示另一种方法来做您想做的事。从控件派生来创建自己的类是非常强大的并且允许最大的灵活性,但也需要最大程度的努力。即便如此,它并不具有纪念意义。

public class CustomTreeView : TreeView
{
    public CustomTreeView() : base()
    {
        this.SetStyle(
            ControlStyles.UserPaint |
            ControlStyles.DoubleBuffer |
            ControlStyles.Opaque, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        using (System.Drawing.SolidBrush BackGroundBrush = new System.Drawing.SolidBrush(System.Drawing.SystemColors.Window))
        using (System.Drawing.SolidBrush ForeGroundBrush = new System.Drawing.SolidBrush(System.Drawing.SystemColors.WindowText))
        using (System.Drawing.SolidBrush BackGroundBrushHighLight = new System.Drawing.SolidBrush(System.Drawing.Color.DarkGreen))
        using (System.Drawing.SolidBrush ForeGroundBrushHighLight = new System.Drawing.SolidBrush(System.Drawing.Color.Pink))
        {
            e.Graphics.FillRectangle(BackGroundBrush, e.ClipRectangle);
            System.Drawing.SolidBrush CurrentNode;

            int count = this.Nodes.Count;
            for (int index = 0; index < count; ++index)
            {
                if (Nodes[index].IsSelected)
                {
                    CurrentNode = ForeGroundBrushHighLight;
                    e.Graphics.FillRectangle(BackGroundBrushHighLight, Nodes[index].Bounds);
                }
                else
                {
                    CurrentNode = ForeGroundBrush;
                }
                e.Graphics.DrawString(Nodes[index].Text, this.Font, CurrentNode, Rectangle.Inflate(Nodes[index].Bounds, 2, 0));
            }

        }
    }
}

【讨论】:

  • 谢谢,我会试试这个。我已经按照您在评论链接中的建议实现了代码,并且基本工作正常,但细节存在问题。我和他们混了一阵子,然后试试这门课。
  • 我正在使用这个类并且遇到了一个问题。 See here
  • @AllLelopath,很抱歉我从来没有收到过台词。您需要在绘图中支持的内容列表是:1) 还处理子节点的线条,2) 概述以便用户可以隐藏整个子结构,以及 3) 子节点的缩进。有很多,但每一个都是可以克服的。如果这听起来比您想要解决的更多,那么您总是可以选择回到所有者绘制技术。就个人而言,我鼓励你继续使用这种方法,因为一旦你完成了,你就会学到很多关于绘画的知识,这将为 C# 中的自定义开辟更多可能性
  • 你能解释一下为什么人们讨厌使用 OnPaint() here 说应该使用 DrawMode 属性吗?
  • 这是一种不同的方法。 OnPaint 要求您做所有事情。所以,这确实意味着更多的工作。
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 2010-09-17
  • 2018-07-15
  • 2014-09-04
  • 2010-11-10
  • 2013-08-04
  • 1970-01-01
  • 2014-12-10
相关资源
最近更新 更多