What is the right way to use OnPaint in .Net applications?

蓝咒 提交于 2019-11-30 23:13:27

To use OnPaint efficiently you have to know a couple things:

  • The OnPaint of a control, e.g. of Form1, is executed everytime the control is painted (duhh...)
  • The OnPaint of Form1 is executed everytime a child control of Form1 is drawn. e.g. If you draw a dot in the upper right corner of Form1 using the OnPaint of Form1, while you have 150 child controls on Form1, the dot will be drawn at least 150 times! It increases render time drastically. Especially if you do alot of custom drawing and calculations in the OnPaint.
    • So as a rule you must never have any logic in the OnPaint of a control, when that control has one or more child controls. Instead you should make a custom control, which holds no more child controls on it, that does the paint job. And place that as a child control on the parent control on the location where the custom drawing is needed.
    • Whenever a control is added onto a parent, the parent will redraw. If you would place alot of controls on another control, e.g. a large result set with checkboxes on Form1, you must use Form1.SuspendLayout() (see: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.suspendlayout.aspx) before you are adding the child controls. And Form1.ResumeLayout() when you are done adding controls. This temporarily supresses the OnPaint event, and decreases render time.
    • Transparencies always increase render time.
    • Placing components in such a way, that there is no background in between them, decreases the number of OnPaint events in the parent control. E.g. place 4 textboxes beneath eachother so that they thouch eachother. So there is no background in between them and the controls are all painted in one OnPaint event instead of 4 OnPaint events. Of course this is not always possible as you do not want to glue all your components side by side. But it is worth to do, if performance is more important than looks, for example in a large custom 'datagrid' of somekind.
    • NEVER change a location or the size of a control in the OnPaint event, as this invokes new OnPaint events. If you must relocate/resize controls, you will have to add that somewhere else in your code, before the OnPaint is invoked. For example, place relocation/resizing code in the OnLayout or OnResize or similar events. If you still think you must place that relocation/resizing code in the OnPaint event in order for you application to work, than you are wrong, and you need to revise the logic of your code.
    • Think System.Math.Pow(2, 2) times before calling Refresh() on a control outside of its own class. If you have the urge to call Refresh you are probably in need of new events and event handlers to stay in sync with what you are willing to display. This is also the case for Invalidate().
    • To check if you are drawing effenciently you can do the following. 1. Open you application 2. put a brake point on OnPaint in the Top Most parent 3. Maxamize a window so it covers your application. 4. Minimize the window again and you application will redraw control by control. If things are drawn double, you have made a mistake in the logic of you application.

Well I guess thats all, if something comes to mind that I forgot, i will update this Q&A. If I have forgotten something, or I made a mistake I would be glad to take note of it!

Hopefully this will give someone a headstart in using custom paint stuff in .Net, as I was looking for this information some time ago.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!