Ce n'est pas le genre de scintillement que le double tampon peut résoudre. Ni BeginUpdate ou SuspendLayout. Vous avez trop de contrôles, BackgroundImage peut faire un beaucoup pire.
Il démarre lorsque UserControl se peint lui-même. Il dessine le BackgroundImage, laissant des trous là où vont les fenêtres de contrôle enfant. Chaque contrôle enfant reçoit alors un message pour se peindre, ils rempliront le trou avec le contenu de leur fenêtre. Lorsque vous disposez de nombreux contrôles, ces trous sont visibles par l'utilisateur pendant un certain temps. Ils sont normalement blancs, contrastant mal avec BackgroundImage lorsqu'il fait sombre. Ou ils peuvent être noirs si le formulaire a sa propriété Opacity ou TransparencyKey définie, ce qui contraste mal avec à peu près tout.
Il s'agit d'une limitation assez fondamentale de Windows Forms, elle est bloquée par la façon dont Windows rend les fenêtres. Corrigé par WPF btw, il n'utilise pas de fenêtres pour les contrôles enfants. Ce que vous souhaitez, c'est la double mise en tampon de l'ensemble du formulaire, y compris les contrôles enfants. C'est possible, vérifiez mon code dans ce fil pour la solution. Il a cependant des effets secondaires et n'augmente pas réellement la vitesse de peinture. Le code est simple, collez ceci dans votre formulaire (pas dans le contrôle utilisateur):
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
Il y a beaucoup de choses que vous pouvez faire pour améliorer la vitesse de peinture, au point que le scintillement n'est plus perceptible. Commencez par vous attaquer à BackgroundImage. Ils peuvent être très coûteux lorsque l'image source est volumineuse et doit être réduite pour s'adapter au contrôle. Modifiez la propriété BackgroundImageLayout sur "Tile". Si cela donne une accélération notable, revenez à votre programme de peinture et redimensionnez l'image pour qu'elle corresponde mieux à la taille de contrôle typique. Ou écrivez du code dans la méthode OnResize () de l'UC pour créer une copie correctement dimensionnée de l'image afin qu'elle n'ait pas à être redimensionnée à chaque fois que le contrôle est repeint. Utilisez le format de pixel Format32bppPArgb pour cette copie, il rend environ 10 fois plus rapide que tout autre format de pixel.
La prochaine chose que vous pouvez faire est d'éviter que les trous ne soient si visibles et contrastent mal avec l'image. Vous pouvez désactiver l'indicateur de style WS_CLIPCHILDREN pour l'UC, l'indicateur qui empêche l'UC de peindre dans la zone où se trouvent les contrôles enfants. Collez ce code dans le code de UserControl:
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
return parms;
}
}
Les contrôles enfants vont maintenant se peindre au-dessus de l'image d'arrière-plan. Vous pourriez encore les voir se peindre un par un, mais le trou blanc ou noir intermédiaire laid ne sera pas visible.
Enfin, la réduction du nombre de contrôles enfants est toujours une bonne approche pour résoudre les problèmes de peinture lente. Remplacez l'événement OnPaint () de l'UC et dessinez ce qui est maintenant affiché dans un enfant. Les étiquettes et PictureBox particulières sont très inutiles. Pratique pour pointer et cliquer, mais leur alternative légère (dessiner une chaîne ou une image) ne prend qu'une seule ligne de code dans votre méthode OnPaint ().
UpdateStyles
après avoir défini ces paramètres? C'est mal documenté, mais peut parfois être nécessaire.