代码之家  ›  专栏  ›  技术社区  ›  Joan Venge

在WinForms中进行自定义控件绘制的最佳实践?

  •  7
  • Joan Venge  · 技术社区  · 15 年前

    通常,当我重写onpaint方法时,我会在其中创建笔和画笔等,然后将它们处理掉。

    我在某个地方也读到过这样的文章,不是重新创建这些笔和画笔等,而是将它们作为静态成员创建一次,然后在表单关闭时处理一次,等等。

    这是更好的做法吗?

    有更好的方法吗?

    我可以假设,因为onpaint被称为1000s(?)有时,与只创建一次GC相比,这会为GC创建大量工作。

    5 回复  |  直到 14 年前
        1
  •  8
  •   SLaks    15 年前

    如果画笔和钢笔没有改变,那么最好创建一次并重新使用它们。但是,请注意,如果控件可能用于多个线程(这是非常不可能的),则应该使它们 ThreadStatic (并在每个线程首次使用时初始化)或使它们成为实例成员(并在控件的 Dispose override);否则,您将得到无法生成的gdi+错误,因为gdi+对象不能同时用于多个线程。图像也是如此。

    如果它们确实发生了更改(例如,如果使用的渐变画笔取决于控件的大小),您可能仍然希望将它们存储在实例字段中,并在控件的大小(或其他)发生更改时重新创建它们。

    注意,顺便说一下,如果你使用普通颜色,你可以使用静态 Brushes Pens 类,其中包含用于所有.NET内置颜色的静态画笔和笔,以及 SystemBrushes SystemPens 系统颜色。

        2
  •  2
  •   Jonathan    14 年前

    我读了一篇文章 interesting article 上个月,它建议在单独的bufferedgraphics对象上进行所有绘制,并让on-paint方法直接从该对象复制到控件的图形对象。

    这样,画图速度就更快了,只有当一些重要的变化(例如,行移动或文本变化)时,才更新Bufferedgraphics。

        3
  •  1
  •   Meta-Knight    15 年前

    我要做的是将画笔和笔作为自定义控件的成员,然后在释放控件时对它们进行处置。这样,每次调用OnPaint时都可以重复使用相同的画笔/笔。

    我不会申报的 static 但是,因为你不知道什么时候可以处理你的对象。但是正如Slaks所提到的,如果在内存中同时存在多个控件实例,那么最好将画笔和笔创建为静态的,以便在应用程序的生命周期内只创建每个对象的一个实例。

        4
  •  1
  •   Daniel MoÅ¡mondor    14 年前

    我真的要看你在画什么。如果要绘制仅因用户交互而重新绘制的内容,可以释放性能顾虑,并在需要时创建所有图形对象。

    确保你 Dispose() 图形中需要的一切。笔、画笔、区域、字体。这些都是GDI对象,并通过GDI句柄绑定到系统中。

    如果您需要以某种方式设置动画或在用户不单击的情况下及时更改的图形,请准备前面的所有图形对象,并尽可能多地重用它们。这里可以应用的规则是,在绘制动画的每一帧时,最好先浪费内存,然后是毫秒。

    最后,至少对于本文来说,不要忘记使用双缓冲,或者在.NET控制系统中使用自动缓冲,或者回滚自己的位图样式。

    祝你玩得开心:)

        5
  •  0
  •   Sorin Comanescu    15 年前

    最好的做法是使用系统笔和刷子,因为这些都是为了最小化资源消耗而优化的。