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, le BackgroundImage peut rendre un lot pire.
Elle commence lorsque le UserControl se peint lui-même. Il dessine l'image d'arrière-plan (BackgroundImage), laissant des trous à l'emplacement des fenêtres des contrôles enfants. Chaque contrôle enfant reçoit alors un message l'invitant à se peindre, il remplit le trou avec le contenu de sa fenêtre. Lorsque vous avez beaucoup de contrôles, ces trous sont visibles par l'utilisateur pendant un certain temps. Ils sont normalement blancs, ce qui contraste fortement avec l'image d'arrière-plan lorsqu'elle est sombre. Ils peuvent aussi ê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, il est coincé avec la façon dont Windows rend Windows. Cela a été corrigé par WPF, qui n'utilise pas Windows pour les contrôles enfants. Ce que vous voulez, c'est une double mise en mémoire 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. Elle a cependant des effets secondaires, et n'augmente pas réellement la vitesse de la 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 aux BackgroundImage. Ils peuvent être vraiment coûteux lorsque l'image source est grande et doit être réduite pour s'adapter au contrôle. Changez la propriété BackgroundImageLayout en "Tile". Si vous constatez une accélération notable, retournez dans votre programme de peinture et redimensionnez l'image pour qu'elle corresponde mieux à la taille typique du contrôle. Ou bien, écrivez du code dans la méthode OnResize() de l'UC pour créer une copie de l'image de taille correcte afin qu'il ne soit pas nécessaire de la redimensionner à chaque fois que le contrôle se repeint. Utilisez le format de pixel Format32bppPArgb pour cette copie, il assure un rendu environ 10 fois plus rapide que tout autre format de pixel.
La prochaine chose que vous pouvez faire est d'éviter que les trous soient si visibles et contrastent mal avec l'image. Vous pouvez éteindre l'indicateur de style WS_CLIPCHILDREN pour l'UC, l'indicateur qui empêche l'UC de peindre dans la zone où vont les contrôles enfants. Collez ce code dans le code du 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 par-dessus l'image de fond. Vous pouvez toujours les voir se peindre un par un, mais l'affreux trou intermédiaire blanc ou noir 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. L'étiquette particulière et la PictureBox sont très gaspilleur. Ils sont pratiques pour le point and click 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().
0 votes
Où sont ces déclarations ? Idéalement, mettez-les dans le constructeur. Avez-vous appelé
UpdateStyles
après les avoir réglés ? C'est mal documenté, mais cela peut parfois être nécessaire.