Nie jest to rodzaj migotania, który może rozwiązać podwójne buforowanie. Ani BeginUpdate ani SuspendLayout. Masz zbyt wiele kontrolek, obraz BackgroundImage może to znacznie pogorszyć.
Rozpoczyna się, gdy UserControl maluje się. Rysuje BackgroundImage, pozostawiając dziury w miejscach, w których znajdują się okna kontroli dzieci. Każdy element sterujący podrzędny otrzymuje następnie komunikat, aby sam się malował, wypełniając otwór zawartością swojego okna. Kiedy masz dużo kontrolek, te dziury są widoczne dla użytkownika przez chwilę. Zwykle są białe i źle kontrastują z obrazem BackgroundImage, gdy jest ciemno. Lub mogą być czarne, jeśli formularz ma ustawioną właściwość Opacity lub TransparencyKey, źle kontrastując z prawie wszystkim.
Jest to dość fundamentalne ograniczenie Windows Forms, utknęło w sposobie renderowania okien przez Windows. Naprawione przez WPF przy okazji, nie używa okien do kontrolek podrzędnych. To, czego chcesz, to podwójne buforowanie całego formularza, w tym kontrolek podrzędnych. To możliwe, sprawdź mój kod w tym wątku, aby znaleźć rozwiązanie. Ma jednak efekty uboczne i tak naprawdę nie zwiększa szybkości malowania. Kod jest prosty, wklej go w formularzu (nie w kontrolce użytkownika):
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
Jest wiele rzeczy, które możesz zrobić, aby przyspieszyć malowanie, do tego stopnia, że migotanie nie jest już zauważalne. Zacznij od rozwiązania BackgroundImage. Mogą być naprawdę drogie, gdy obraz źródłowy jest duży i trzeba go zmniejszyć, aby pasował do kontroli. Zmień właściwość BackgroundImageLayout na „Tile”. Jeśli daje to zauważalne przyspieszenie, wróć do programu do malowania i zmień rozmiar obrazu, aby lepiej pasował do typowego rozmiaru elementu sterującego. Lub napisz kod w metodzie OnResize () UC, aby utworzyć kopię obrazu o odpowiednim rozmiarze, tak aby nie trzeba było zmieniać rozmiaru za każdym razem, gdy formant jest malowany. Użyj formatu pikseli Format32bppPArgb dla tej kopii, renderuje ona około 10 razy szybciej niż jakikolwiek inny format pikseli.
Następną rzeczą, którą możesz zrobić, jest zapobieganie takiemu zauważaniu dziur i złemu kontrastowaniu z obrazem. Możesz wyłączyć flagę stylu WS_CLIPCHILDREN dla UC, flagę, która zapobiega malowaniu UC w obszarze, do którego przechodzą kontrolki potomne. Wklej ten kod w kodzie UserControl:
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
return parms;
}
}
Elementy sterujące podrzędne będą teraz malować się na obrazie tła. Nadal możesz zobaczyć, jak malują się jeden po drugim, ale brzydka pośrednia biała lub czarna dziura nie będzie widoczna.
Wreszcie, zmniejszenie liczby kontroli dzieci jest zawsze dobrym podejściem do rozwiązywania problemów z powolnym malowaniem. Zastąp zdarzenie OnPaint () UC i narysuj to, co jest teraz pokazane w dziecku. Poszczególne etykiety i PictureBox są bardzo marnotrawne. Wygodne do wskazywania i klikania, ale ich lekka alternatywa (rysowanie ciągu znaków lub obrazu) zajmuje tylko jeden wiersz kodu w metodzie OnPaint ().
UpdateStyles
po ustawieniu tych? Jest to źle udokumentowane, ale czasami może być konieczne.