TreeView所有者绘制异常

时间:2018-06-12 11:10:20

标签: c# winforms visual-studio-2017 treeview

我使用的是Microsoft Visual Studio社区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

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

这是TreeView中的错误还是我在主人抽签中做错了什么?

1 个答案:

答案 0 :(得分:1)

当双击和一组调用具有 DrawNode 的边界矩形时,会经常调用Empty事件。

(也许原因是:如果所有的绘画只在空矩形中发生,则不会显示任何内容。嗯..)

作为解决方法,您可以快捷 DrawNode事件,以便在事件开始时针对所有错误的调用:

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,因为它会改善几个缺点。