Проблемы WinForms Invalidate(), перерисовка максимально быстраяC#

Место общения программистов C#
Anonymous
Проблемы WinForms Invalidate(), перерисовка максимально быстрая

Сообщение Anonymous »

Я хочу перерисовать свою WinForm как можно быстрее, но при этом вести себя хорошо и сохранить работоспособность элементов управления в форме. Я избегаю использования Update() и Refresh(), поскольку эти методы вызывают перерисовку формы. Я просто хочу, чтобы его перерисовали в ближайшее подходящее время. Поэтому я вызываю Invalidate() в конце моего метода OnPaint(), который должен просто сигнализировать о том, что форма должна быть перерисована, когда для этого есть время. Частота обновления очень хорошая, но ComboBox не отображается, пока я не щелкну по нему или не перемещу окно. Это заставляет меня чувствовать, что это неправильный способ запросить перерисовку как можно быстрее:

Код: Выделить всё

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();
}
}
Изображение

Если я перенесу вызов Invalidate() в другой поток, работающий в фоновом режиме, все будет то же самое. Но если я добавлю Thread.Yield() для хорошей игры, поле со списком будет нарисовано.

Код: Выделить всё

ThreadPool.QueueUserWorkItem(_ =>
{
while(!IsDisposed)
{
Invalidate();
Thread.Yield();
}
});
Изображение

Однако этот пример немного менее сложен, чем моя реальная программа, поэтому я добавил Thread.Sleep(10) в свой метод OnPaint, чтобы имитировать более сложный рисунок. Затем я снова возвращаюсь к тому, что ComboBox не отображается.

Код: Выделить всё

  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);
}
Мне действительно не хочется регулировать задержку фонового потока в зависимости от времени выполнения метода OnPaint.
Как правильно Как любезно запросить перерисовку как можно быстрее, не создавая проблем для остальной части формы?

Подробнее здесь: https://stackoverflow.com/questions/790 ... s-possible

Вернуться в «C#»