By default, a control is redrawn any time one of its properties changes. While this may be convenient much of the time, it can be quite inefficient if several properties need to be updated together because the control will redraw after each property change.
Imagine you have a lamp that you'd like to “turn on” in response to a digital input on a PLC. However, in addition to “turning on”, you also want to update its Text
and Font
properties at runtime. It may be tempting to implement this operation somewhat like the following:
void UpdateLamp(bool isOn) { // Lamp will redraw here... lamp.IsOn = isOn; // ...here... lamp.Text = lamp.IsOn ? "ON" : "OFF"; // ...and here... lamp.Font = new Font(Font.Name, Font.Size, lamp.IsOn ? FontStyle.Bold : FontStyle.Regular); }
The code above will redraw the lamp 3 times, when only one draw is needed. While it may not be noticeable with a single control, the effect becomes more apparent with the addition of more controls.
To remedy the problem, the SuspendDraw
method can be use to suspend the control's drawing operations until the control's state is fully updated. Then the ResumeDraw
method can be used to resume and initiate the control's drawing operations.
void UpdateLamp(bool isOn) { lamp.SuspendDraw(); // lamp will not redraw here lamp.IsOn = isOn; // ...or here... lamp.Text = lamp.IsOn ? "ON" : "OFF"; // ...or here... lamp.Font = new Font(Font.Name, Font.Size, lamp.IsOn ? FontStyle.Bold : FontStyle.Regular); // lamp will redraw here lamp.ResumeDraw(); }
In addition to making the display appear less jittery, this method also provides significant performance benefits.
Please note that every call to SuspendDraw
increments a counter, and every call to ResumeDraw
decrements that counter. Both methods return this count when called. ResumeDraw
will only initiate the control's drawing routines when the count reaches 0. In other words, for every call to SuspendDraw
there must eventually be a matching call to ResumeDraw
for the control's drawing routines to be initiated.