代码之家  ›  专栏  ›  技术社区  ›  lurker

TreeView所有者绘制异常

  •  2
  • lurker  · 技术社区  · 6 年前

    我使用的是Microsoft Visual Studio Community 2017版本15.7.2和.NET Framework版本4.7.03056。

    我在用winforms TreeView 并修改其默认行为,使其更像windows资源管理器树视图。我设置了以下属性:

    LineHeight`    22
    DrawMode       OwnerDrawAll
    

    我用下面的 DrawNode 事件。此代码使用右括号和下括号位图(16x16)显示展开或未展开的节点,并使用自定义颜色进行选择/聚焦突出显示。没有什么异国情调。

    private void treeDir_DrawNode(object sender, DrawTreeNodeEventArgs e)
    {
        const int indent = 12;
        const int markerSpacing = 20;
    
        int leftPos = e.Bounds.Left + e.Node.Level * indent;
        Brush selectBrush;
        Pen pen;
        Graphics g = e.Graphics;
    
        e.DrawDefault = false;
    
        if (e.Node.IsSelected)
        {
            if (e.Node.TreeView.Focused)
            {
                selectBrush = new SolidBrush(FocusedBackgroundColor);
                pen = new Pen(new SolidBrush(FocusedPenColor));
            }
            else
            {
                selectBrush = new SolidBrush(UnfocusedBackgroundColor);
                pen = new Pen(new SolidBrush(UnfocusedPenColor));
            }
    
            g.FillRectangle(selectBrush, e.Bounds);
            g.DrawRectangle(pen, e.Bounds);
        }
    
        if (e.Node.Nodes.Count > 0)
        {
            if (e.Node.IsExpanded)
            {
                g.DrawImage(Properties.Resources.Expanded, leftPos+2, e.Bounds.Top+2);
            }
            else
            {
                g.DrawImage(Properties.Resources.Unexpanded, leftPos+2, e.Bounds.Top+2);
            }
        }
    
        g.DrawString(
            e.Node.Text, CommonFont, new SolidBrush(Color.Black), leftPos + markerSpacing, e.Bounds.Top+2);
    }
    

    现在的情况是,当表单第一次显示时,如果我展开不是第一个节点的节点,它也会覆盖(透明地覆盖)第一个节点文本。这是顺序。

    表单启动时:

    enter image description here

    然后双击节点4:

    enter image description here

    如果双击第一个节点,问题就解决了:

    enter image description here

    从现在开始,如果双击node 4,问题就不会再出现。双击第一个节点可以清除该问题,并在节点4的该点之后的表单生命周期内避免该问题。但是,如果我再向下双击另一个可扩展节点,则会再次发生这种情况。

    这是窃听器吗 树视图 或者我在我的主人画里做了不正确的事?

    1 回复  |  直到 6 年前
        1
  •  1
  •   TaW    6 年前

    这个 DrawNode 当双击和一组调用有一个边界矩形时,调用事件的频率太高,即 Empty .

    (可能原因是:如果所有绘图都只在空矩形中进行,则不会显示任何内容。)Hm.)

    所以作为一个 解决办法 你可以 捷径 这个 拖曳节点 事件开始时所有错误调用的事件:

    if (e.Bounds.Height < 1 || e.Bounds.Width < 1) return;
    

    我也推荐这样的文本呈现:

    TextRenderer.DrawText(g, e.Node.Text, CommonFont, 
                          new Point( leftPos + markerSpacing, e.Bounds.Top+2), Color.Black);
    

    TextRenderer 总是被推荐 Graphics.DrawString 因为它改进了一些缺点。