【问题标题】:TreeView Owner Draw AnomalyTreeView 所有者绘制异常
【发布时间】:2018-06-12 11:10:20
【问题描述】:

我正在使用 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);
}

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

表单启动时:

然后我双击节点 4:

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

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

这是TreeView 中的错误还是我在我的所有者抽奖中做错了什么?

【问题讨论】:

  • 当您阅读它们时,节点的边界似乎没有正确定义。我个人从未使用过它,而是使用控件的项目高度。
  • @Franck 但我需要e.Bounds 来获得矩形的正确起始位置。控制项高度信息不足以进行绘图。 e.Graphics 的画布是整个TreeView 控件,而不仅仅是节点。如果我不使用e.Bounds,我还能如何找到节点的边界?
  • 你是对的。我弄错了treeview ondraw和node ondraw。我有解决方案,我会发布答案。

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


【解决方案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,因为它改进了几个缺点。

【讨论】:

  • 是的,我似乎收到了一个额外的错误平局事件。我会修补这个 hack。
  • 其实我通过this post的观察改进了它
  • 感谢您的更新。有趣的是,我阅读了您提供的链接,并且该答案的作者对HeightWidth 使用了防御性检查,没有发表评论。在我的代码中的其他场景中,我使用了TextRenderer,发现它克服了一些问题。我想我有点懒惰,只是在这次活动中打了一个DrawString 电话。感谢您回复TextRenderer。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 2014-02-18
  • 2013-01-29
  • 1970-01-01
  • 2023-03-03
相关资源
最近更新 更多