有时我需要一个控件的自定义外观。或者做很多自定义绘画。我知道我可以用 OnPaint 做到这一点(请参阅: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.onpaint.aspx )

使用 OnPaint 在 .net 应用程序上自定义绘制内容的正确方法是什么?是否有任何规则我必须牢记以保持我的应用程序优化并将渲染时间保持在最低限度?

注意:我不时看到并经历了许多 OnPaint 的低效使用,因此我创建了这个问答。

最佳答案

要有效地使用 OnPaint,您必须了解以下几点:

  • 控件的 OnPaint,例如Form1 , 每次绘制控件时都会执行 (duhh...)
  • 每次绘制OnPaint子控件时,都会执行Form1Form1。例如如果你使用 Form1OnPaintForm1 的右上角画一个点,而你在 Form1 上有 150 个子控件,那么这个点至少会被画 150 次!它大大增加了渲染时间。特别是如果您在 OnPaint 中进行了大量自定义绘图和计算。
  • 所以作为一项规则,当一个控件有一个或多个子控件时,你不能在控件的 OnPaint 中有任何逻辑。相反,您应该制作一个自定义控件,它上面不再包含子控件,来完成绘制工作。并将其作为子控件放置在需要自定义绘图的位置的父控件上。
  • 每当控件添加到父级时,父级将重绘。如果你想在另一个控件上放置很多控件,例如Form1 上带有复选框的大型结果集,您必须在添加子控件之前使用 Form1.SuspendLayout()(请参阅: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.suspendlayout.aspx )。完成添加控件后的 Form1.ResumeLayout()。这会暂时抑制 OnPaint 事件,并减少渲染时间。
  • 透明度总是会增加渲染时间。
  • 以这样一种方式放置组件,在它们之间没有背景,减少父控件中 OnPaint 事件的数量。例如。将 4 个文本框放在彼此下方,以便它们彼此接触。因此,它们之间没有背景,控件全部绘制在一个 OnPaint 事件中,而不是 4 个 OnPaint 事件中。当然,这并不总是可行的,因为您不想并排粘合所有组件。但这是值得做的,如果性能比外观更重要,例如在某种大型自定义“数据网格”中。
  • 永远不要更改 OnPaint 事件中控件的位置或大小,因为这会调用新的 OnPaint 事件。如果必须重新定位/调整控件大小,则必须在调用 OnPaint 之前将其添加到代码中的其他位置。例如,将重定位/调整大小代码放在 OnLayoutOnResize 或类似事件中。如果您仍然认为必须将重定位/调整大小代码放在 OnPaint 事件中才能使您的应用程序工作,那么您就错了,您需要修改代码的逻辑。
  • 思考 System.Math.Pow(2, 2) 次,然后在其自己的类 之外对控件 调用 Refresh() 。如果您有调用 Refresh 的冲动,您可能需要新的事件和事件处理程序来与您愿意显示的内容保持同步。 Invalidate() 也是这种情况。
  • 要检查您的绘图是否有效,您可以执行以下操作。 1. 打开您的应用程序 2. 在 Top Most 父级中的 OnPaint 上设置制动点 3. 最大化一个窗口,使其覆盖您的应用程序。 4. 再次最小化窗口,您的应用程序将逐个重新绘制控件。如果事情是双重的,那么您在应用程序的逻辑中犯了一个错误。

  • 好吧,我想就是这样,如果我想起了我忘记的事情,我会更新这个问答。如果我忘记了什么,或者我犯了一个错误,我会很高兴注意到它!

    希望这能让某人在 .Net 中使用自定义绘制的东西有一个先机,因为我前段时间一直在寻找这些信息。

    关于.net - 在 .Net 应用程序中使用 OnPaint 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13652568/

    10-09 09:36