Это не такое мерцание, которое может решить двойная буферизация. Не начинайте или не приостанавливайте. У вас слишком много элементов управления, BackgroundImage может сделать это лот хуже.
Начинается, когда сам UserControl красит себя. Он рисует BackgroundImage, оставляя дыры, где идут дочерние окна управления. Затем каждый дочерний элемент получает сообщение для рисования, они заполняют отверстие содержимым окна. Когда у вас много элементов управления, эти дыры видны пользователю некоторое время. Они обычно белые, плохо контрастируют с BackgroundImage, когда темно. Или они могут быть черными, если форма имеет свой набор свойств Opacity или TransparencyKey, что плохо контрастирует с чем угодно.
Это довольно фундаментальное ограничение Windows Forms, оно застряло в том, что Windows создает окна. Исправлено с помощью WPF btw, оно не использует окна для дочерних элементов управления. То, что вы хотите, - это двойная буферизация всей формы, включая дочерние элементы управления. Это возможно, проверьте мой код в this thread для решения. Тем не менее, он имеет побочные эффекты и фактически не увеличивает скорость окраски. Код прост, вставьте в форму (не пользовательский элемент управления):
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 раз быстрее, чем любой другой формат пикселей.
Следующее, что вы можете сделать, - это не допустить, чтобы отверстия были настолько заметны и плохо контрастировали с изображением. Вы можете указать turn off флаг стиля WS_CLIPCHILDREN для UC, флаг, который предотвращает рисование UC в области, куда идут элементы управления child. Вставьте этот код в коде UserControl в:
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
return parms;
}
}
контролирует ребенок теперь окрашиваются поверх фонового изображения. Вы все еще можете видеть, как они рисуют сами по себе, но уродливая промежуточная белая или черная дыра не будет видна.
И последнее, но не менее важное: сокращение количества детских элементов управления всегда является хорошим подходом к решению проблем медленной живописи. Переопределите событие OnPaint() UC и нарисуйте то, что теперь показано в дочернем элементе. Особые ярлыки и PictureBox - очень расточительный. Удобный для точки и клика, но их легкая альтернатива (рисование строки или изображения) занимает только одну строку кода в вашем методе OnPaint().
Где эти заявления? В идеале поместите их в конструктор. Вы назвали «UpdateStyles» после их установки? Это плохо документировано, но иногда может быть необходимо. – Thomas