Подвійне буферування може вирішити не такий тип мерехтіння. Ні BeginUpdate або SuspendLayout. У вас занадто багато елементів керування, BackgroundImage може зробити це набагато гірше.
Він починається, коли UserControl малює себе. Він малює BackgroundImage, залишаючи отвори, куди йдуть дочірні вікна управління. Кожен контрольний діть потім отримує повідомлення, щоб намалювати себе, вони заповнить отвір вмістом вікна. Якщо у вас є багато елементів керування, ці отвори видно користувачеві деякий час. Вони зазвичай білі, погано контрастують з BackgroundImage, коли темно. Або вони можуть бути чорними, якщо у формі встановлено властивість Opacity або TransparencyKey, що погано контрастує з практично будь-чим.
Це досить фундаментальне обмеження Windows Forms, воно застрягло в тому, як Windows надає вікна. Виправлений WPF btw, він не використовує вікна для дочірнього контролю. Що ви хочете, це подвійне буферизація всієї форми, включаючи дочірні контролі. Це можливо, перевірте мій код у цій темі на рішення. Однак він має побічні ефекти, але насправді не збільшує швидкість фарбування. Код простий, вставте його у свою форму (а не контроль користувача):
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 та намалюйте те, що зараз показано дитині. Конкретні етикетки та PictureBox дуже марнотратні. Зручний для точки та клацання, але їх легка альтернатива (малювання рядка чи зображення) містить лише один рядок коду у вашому методі OnPaint ().
UpdateStyles
після встановлення цих? Це погано задокументовано, але іноді може знадобитися.