Это не тот вид мерцания, который может решить двойная буферизация. Ни BeginUpdate, ни SuspendLayout. У вас слишком много элементов управления, BackgroundImage может сделать его намного хуже.
Он запускается, когда UserControl рисует себя. Он рисует BackgroundImage, оставляя дыры там, где находятся окна дочерних элементов управления. Затем каждый дочерний элемент управления получает сообщение, которое нужно нарисовать, и они заполняют пустоту содержимым своего окна. Когда у вас много элементов управления, эти дыры какое-то время видны пользователю. Обычно они белые, плохо контрастирующие с BackgroundImage в темноте. Или они могут быть черными, если для формы установлено свойство Opacity или TransparencyKey, что плохо контрастирует практически с чем угодно.
Это довольно фундаментальное ограничение Windows Forms, оно связано с тем, как Windows отображает окна. Исправлено WPF, кстати, он не использует окна для дочерних элементов управления. Вам нужна двойная буферизация всей формы, включая дочерние элементы управления. Это возможно, проверьте мой код в этой ветке для решения. Однако у него есть побочные эффекты и на самом деле скорость рисования не увеличивается. Код прост, вставьте его в свою форму (не в пользовательский элемент управления):
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
Есть много вещей, которые вы можете сделать, чтобы улучшить скорость рисования до такой степени, что мерцание больше не будет заметно. Начните с решения BackgroundImage. Они могут быть очень дорогими, если исходное изображение велико и его нужно уменьшить, чтобы он соответствовал элементу управления. Измените свойство BackgroundImageLayout на «Плитка». Если это дает заметное ускорение, вернитесь в свою программу рисования и измените размер изображения, чтобы оно лучше соответствовало типичному размеру элемента управления. Или напишите код в методе UC OnResize (), чтобы создать копию изображения нужного размера, чтобы его не приходилось изменять каждый раз при перерисовке элемента управления. Используйте для этой копии формат пикселей Format32bppPArgb, он отображается примерно в 10 раз быстрее, чем любой другой формат пикселей.
Следующее, что вы можете сделать, это сделать так, чтобы дыры не были настолько заметными и плохо контрастировали с изображением. Вы можете отключить флаг стиля WS_CLIPCHILDREN для UC, флаг, который предотвращает рисование UC в области, где находятся дочерние элементы управления. Вставьте этот код в код UserControl:
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
return parms;
}
}
Дочерние элементы управления теперь будут рисовать себя поверх фонового изображения. Вы все еще можете видеть, как они рисуют себя один за другим, но уродливая промежуточная белая или черная дыра не будет видна.
И последнее, но не менее важное: сокращение количества дочерних элементов управления всегда является хорошим подходом к решению проблем с медленным рисованием. Переопределите событие OnPaint () UC и нарисуйте то, что теперь отображается в дочернем элементе. Особый ярлык и PictureBox очень расточительны. Удобно указывать и щелкать, но их легкая альтернатива (рисование строки или изображения) требует только одной строки кода в вашем методе OnPaint ().
UpdateStyles
после установки этих? Это плохо задокументировано, но иногда может быть необходимо.