Non è il tipo di sfarfallio che il doppio buffering può risolvere. Né BeginUpdate o SuspendLayout. Hai troppi controlli, BackgroundImage può renderlo molto di peggio.
Inizia quando UserControl si dipinge. Disegna l'immagine di sfondo, lasciando dei buchi dove vanno le finestre di controllo figlio. Ogni controllo figlio riceve quindi un messaggio per dipingere se stesso, riempiranno il buco con il contenuto della finestra. Quando si hanno molti controlli, questi buchi sono visibili all'utente per un po '. Normalmente sono bianchi e contrasta male con l'immagine di sfondo quando è buio. Oppure possono essere neri se il modulo ha la sua proprietà Opacity o TransparencyKey impostata, che contrasta male con qualsiasi cosa.
Questa è una limitazione piuttosto fondamentale di Windows Forms, è legata al modo in cui Windows esegue il rendering di Windows. Risolto da WPF btw, non utilizza finestre per i controlli figlio. Quello che vorresti è il doppio buffering dell'intero modulo, inclusi i controlli figlio. È possibile, controlla il mio codice in questo thread per la soluzione. Tuttavia, ha effetti collaterali e in realtà non aumenta la velocità di pittura. Il codice è semplice, incollalo nel modulo (non nel controllo utente):
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
Ci sono molte cose che puoi fare per migliorare la velocità di pittura, al punto che lo sfarfallio non si nota più. Inizia affrontando l'immagine di sfondo. Possono essere molto costosi quando l'immagine di origine è grande e deve essere ridotta per adattarsi al controllo. Modificare la proprietà BackgroundImageLayout in "Tile". Se questo dà una notevole velocità, torna al tuo programma di pittura e ridimensiona l'immagine per adattarla meglio alle dimensioni tipiche del controllo. Oppure scrivi il codice nel metodo OnResize () dell'UC per creare una copia dell'immagine di dimensioni adeguate in modo che non debba essere ridimensionata ogni volta che il controllo viene ridisegnato. Usa il formato pixel Format32bppPArgb per quella copia, rende circa 10 volte più veloce di qualsiasi altro formato pixel.
La prossima cosa che puoi fare è impedire che i fori siano così evidenti e contrastino male con l'immagine. È possibile disattivare il flag di stile WS_CLIPCHILDREN per UC, il flag che impedisce all'UC di disegnare nell'area in cui si trovano i controlli figlio. Incolla questo codice nel codice di UserControl:
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
return parms;
}
}
I controlli figlio ora dipingeranno se stessi sopra l'immagine di sfondo. Potresti ancora vederli dipingersi uno per uno, ma il brutto buco bianco o nero intermedio non sarà visibile.
Ultimo ma non meno importante, ridurre il numero di controlli figlio è sempre un buon approccio per risolvere i problemi di pittura lenta. Ignora l'evento OnPaint () dell'UC e disegna ciò che ora viene mostrato in un bambino. Etichetta particolare e PictureBox sono molto dispendiosi. Comodo per punta e clicca ma la loro alternativa leggera (disegnare una stringa o un'immagine) richiede solo una singola riga di codice nel tuo metodo OnPaint ().
UpdateStyles
dopo averli impostati? È mal documentato, ma a volte può essere necessario.