Это не тот тип мерцания, который может решить двойная буферизация. Ни BeginUpdate, ни SuspendLayout. У вас слишком много элементов управления, BackgroundImage может сделать его много хуже.
Запускается, когда пользовательский элемент управления рисует сам. Он рисует 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 на «Плитка». Если это дает заметное ускорение, вернитесь к своей программе рисования и измените размер изображения, чтобы оно лучше соответствовало типичному размеру элемента управления. Или напишите код в методе OnResize () UC, чтобы создать копию изображения правильного размера, чтобы его не нужно было изменять каждый раз, когда элемент управления перерисовывается. Используйте для этой копии пиксельный формат 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 и нарисуйте то, что сейчас показано у дочернего элемента. Конкретные Label и PictureBox являются очень расточительными. Удобно для указания и щелчка, но их легкая альтернатива (рисование строки или изображения) занимает только одну строку кода в вашем методе OnPaint ().