I want to redraw my WinForm as fast as possible, but still play nice and keep the controls in the form working. I avoid using Update() and Refresh() since those methods force a redraw of the form. I just want it to be redrawn at the next suitable time. So I call Invalidate() at the end of my OnPaint() method, which should just signal that the form should be repainted whenever there is time for it. The refresh rate is very good, but the ComboBox is not drawn until I click it or move the window. Which makes me feel that this is not the correct way to request redraws as fast as possible:
public class TimeForm : Form
{
private readonly ComboBox _mode = new ComboBox();
private readonly Font _font = new Font("Verdana", 20, FontStyle.Regular, GraphicsUnit.Pixel);
public TimeForm()
{
SuspendLayout();
_mode.Location = new Point(10, 10);
_mode.Size = new Size(280, 23);
_mode.DropDownStyle = ComboBoxStyle.DropDownList;
_mode.Items.Add("Standard");
_mode.SelectedIndex = 0;
ClientSize = new Size(300, 100);
Controls.Add(_mode);
ResumeLayout(false);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
DoubleBuffered = true;
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawString(DateTime.Now.ToString("HH:mm:ss.fff"), _font, Brushes.Black, 10, 50);
Invalidate();
}
}
If I move the call to Invalidate() to another thread running in the background, things are the same. But if I add a Thread.Yield() to play nice, the ComboBox is drawn.
ThreadPool.QueueUserWorkItem(_ =>
{
while(!IsDisposed)
{
Invalidate();
Thread.Yield();
}
});
However, this example is a bit less complex than my real program so I added a Thread.Sleep(10) in my OnPaint method to simulate a more complex drawing. Then I’m back to the ComboBox not being drawn.
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawString(DateTime.Now.ToString("HH:mm:ss.fff"), _font, Brushes.Black, 10, 50);
Thread.Sleep(10);
}
I really don’t want to adjust the delay in the background thread depending on the execution time of the OnPaint method.
What is the proper way to kindly request a redraw as quickly as possible, without causing problem for the rest of the form?
9