Even after years you always have something to learn...this time I had a windows forms application with a lot of graphics in it: big and heavy background images, graphic buttons with transparent background, mixed bitmaps, Jpegs and PNGs...the whole thing rendering performance was just...horrible! The form was rending slowly piece by piece (with a lot of artifacts) giving the user a very poor feeling.
To improve the rendering speed you can use some standard techniques, here are a couple of them:
- Calling BeginUpdate() before populating data intensive controls (ComboBox, ListBox DataGrid, etc...) and EndUpdate() when done.
- Calling SuspendLayout() and ResumeLayout() on parent controls and forms to optimize layout changes. Bounds, Size, Location, Visible, and Text for AutoSize controls causes the layout changes. You should call these methods when performing multiple layout changes and always on parent control of the controls that you are changing layout for.
However the biggest impact was given when I changed the following properties:
- Avoid using BackColor=Transparent when it’s not strictly needed, windows forms transparency is done with a two pass rendering, so prefer solid colors whenever possible.
- If you use BackgroundImage heavily and with very large images do not underestimate the impact of changing the BackgroundImageLayout property too: the default value it’s ‘Tile’ which means that the rendering engine will do additional computations to figure out if it have to replicate it horizontally and vertically and this is a big show stopper when dealing with performances! Change it to ‘none’ or to the value most appropriate for you (to be honest ‘none’ should be the default value here).
- Set the DoubleBuffered property to true (you need to use reflection if you want to set this on dynamically created controls because it’s a protected method) or use:
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);in your control’s constructor.
My recommendation is to change the BackgroundImageLayout from the default ‘Tile’ value to something else (if you don’t really need the tile behavior) for all the controls that use a Background Image, the speed-up in rendering was surprising.
If you use PictureBoxes too, check the ‘SizeMode’ and set it to an appropriate value in order to reduce unnecessary scaling of the images.