Ini bukan jenis flicker yang dapat diatasi dengan buffer ganda. Maupun BeginUpdate atau SuspendLayout. Anda memiliki terlalu banyak kontrol, BackgroundImage bisa membuatnya jauh lebih buruk.
Ini dimulai saat UserControl mengecat dirinya sendiri. Ini menggambar BackgroundImage, meninggalkan lubang di mana jendela kontrol anak berada. Setiap kontrol anak kemudian mendapat pesan untuk melukis dirinya sendiri, mereka akan mengisi lubang dengan konten jendela mereka. Jika Anda memiliki banyak kontrol, lubang itu akan terlihat oleh pengguna untuk sementara waktu. Mereka biasanya berwarna putih, sangat kontras dengan BackgroundImage saat gelap. Atau mereka bisa menjadi hitam jika formulir memiliki properti Opacity atau TransparencyKey, sangat kontras dengan apa saja.
Ini adalah batasan yang cukup mendasar dari Windows Forms, ini terjebak dengan cara Windows merender jendela. Diperbaiki oleh WPF btw, tidak menggunakan windows untuk kontrol anak. Yang Anda inginkan adalah melakukan buffer ganda pada seluruh formulir, termasuk kontrol anak. Itu mungkin, periksa kode saya di utas ini untuk solusinya. Ini memiliki efek samping, dan tidak benar-benar meningkatkan kecepatan melukis. Kodenya sederhana, tempelkan ini di formulir Anda (bukan kontrol pengguna):
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
Ada banyak hal yang bisa Anda lakukan untuk meningkatkan kecepatan mengecat, sampai-sampai kedipan tidak terlihat lagi. Mulailah dengan menangani BackgroundImage. Harganya bisa sangat mahal jika gambar sumbernya besar dan perlu diciutkan agar sesuai dengan kontrol. Ubah properti BackgroundImageLayout menjadi "Tile". Jika itu memberikan percepatan yang nyata, kembali ke program pengecatan Anda dan ubah ukuran gambar agar lebih cocok dengan ukuran kontrol biasa. Atau tulis kode dalam metode OnResize () UC untuk membuat salinan gambar dengan ukuran yang tepat sehingga tidak perlu diubah ukurannya setiap kali kontrol menggambar ulang. Gunakan format piksel Format32bppPArgb untuk salinan itu, ini merender sekitar 10 kali lebih cepat daripada format piksel lainnya.
Hal berikutnya yang dapat Anda lakukan adalah mencegah lubang agar tidak terlalu terlihat dan sangat kontras dengan gambar. Anda bisa mematikan bendera gaya WS_CLIPCHILDREN untuk UC, bendera yang mencegah UC mengecat di area tempat kontrol anak berada. Tempel kode ini di kode UserControl:
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
return parms;
}
}
Kontrol anak sekarang akan mewarnai dirinya sendiri di atas gambar latar belakang. Anda mungkin masih melihat mereka mengecat dirinya sendiri satu per satu, tetapi lubang putih atau hitam di tengah yang jelek tidak akan terlihat.
Last but not least, mengurangi jumlah kontrol anak selalu merupakan pendekatan yang baik untuk menyelesaikan masalah melukis yang lambat. Ganti acara OnPaint () UC dan gambar apa yang sekarang ditampilkan pada anak. Label dan PictureBox tertentu sangat boros. Nyaman untuk tunjuk dan klik tetapi alternatifnya yang ringan (menggambar string atau gambar) hanya membutuhkan satu baris kode dalam metode OnPaint () Anda.
UpdateStyles
setelah menyetel ini? Ini didokumentasikan dengan buruk, tetapi terkadang mungkin diperlukan.