7
votes

Meilleure pratique pour la peinture de contrôle personnalisée dans Winforms?

Normalement, lorsque je remplace la méthode Onpaint, je crée des stylos et des brosses, etc. à l'intérieur, puis les disposer.

J'ai également lu quelque part qui au lieu de recréer ces stylos et ces brosses, etc. pour les créer une fois en tant que membres statiques, puis les disposer une fois lorsque le formulaire est fermé, etc.

Est-ce une meilleure pratique?

Y a-t-il un meilleur moyen pour cela?

Je peux supposer que, puisque ONPAINT s'appelle des 1000 (?) de fois, cela créerait beaucoup de travail pour le GC par rapport à la création d'une seule fois.


0 commentaires

5 Réponses :


9
votes

Si les brosses et les stylos ne changent pas, il est certainement préférable de les créer une fois et de les réutiliser. Notez cependant que si votre commande peut être utilisée sur plusieurs threads (ce qui est très improbable), vous devez les créer threadstatic (et initialiser la première utilisation par fil) ou les faire d'instance (et DÉPOSERZ-LES DANS VOTRE CONTROLE DISPOSER NOUVELLEDIDE); Sinon, vous obtiendrez des erreurs GDI + non reproductibles, car les objets GDI + ne peuvent pas être utilisés sur plusieurs threads à la fois. Il en va de même pour les images.

Si les éléments changent (par exemple, si vous utilisez des brosses à gradient qui dépendent de la taille de la commande), vous voudrez peut-être toujours les stocker dans des champs d'instance et les recréer lorsque la taille de la commande (ou autre) changements. < / p>

Remarque, d'ailleurs, que si vous utilisez des couleurs normales, vous pouvez utiliser le statique brosses et stylos classes, qui contiennent des brosses statiques et des stylos pour toutes les couleurs intégrées de .NET et Systembrushes et Systempens pour les couleurs du système.


5 commentaires

Merci, une autre question: quand et comment appelleriez-vous la méthode d'expulsion du contrôle? Je ne l'ai jamais appelé sur le contrôle avant.


Vous n'avez pas besoin de l'appeler; .NET l'appellera lorsque la commande parent est disposée (lorsque vous disposez du formulaire que cela se trouve). Si c'est sur votre forme principale, il sera disposé à la fin de l'appel de l'application .Run .


Merci Slaks. Une dernière chose :) Puisque j'utilise généralement un seul formulaire, si je crée une autre forme qui n'est pas une forme principale, je dois le disposer après sa fermeture?


Les formes ne disposent automatiquement automatiquement lorsqu'elles sont fermées s'ils ont été montrés avec .Show ou application.Run (ou équivalent). Les formulaires montrent avec .Showdialog sont pas disposés quand ils sont fermés.


@Homeinastar: Oui, tu as raison; Je n'ai pas lu la méthode avec précaution suffisamment. Lorsque vous appelez showdialog , il est préférable d'envelopper le code dans un à l'aide de instruction.



1
votes

Ce que je ferais, c'est avoir les pinceaux et les stylos comme membres du contrôle personnalisé, puis les disposer lors de la mise au rebut de la commande. De cette façon, vous réutilisez le même pinceau / le même stylo à chaque fois que vous appellez.

Je ne les déclarerais pas statique car vous ne seriez pas capable de savoir quand vous pouvez disposer de vos objets. Mais comme les Slass mentionnés, s'il existe de nombreuses instances du contrôle en mémoire en même temps, il peut être judicieux de créer des brosses et des stylos comme statique afin que vous n'ayez qu'une seule instance de chaque objet créé pour la durée de vie de votre application. .


2 commentaires

S'il y aura beaucoup d'instances du contrôle, ce serait une très bonne idée de les rendre statiques. Il n'y a rien de mal à avoir quelques brosses suspendues.


C'est un bon point, s'il y a beaucoup d'instances de ce contrôle, rendant les brosses et les stylos statiques seraient une bonne idée.



0
votes

Une meilleure pratique serait d'utiliser des stylos et des pinceaux système, car ils sont optimisés pour une consommation de ressources minimale.


1 commentaires

Seulement s'il utilise des couleurs intégrées statiques.



2
votes

J'ai lu un Article intéressant le mois dernier qui suggéré de faire toute votre peinture sur un objet de bufferedgraphics séparé et que la méthode On_paint est une copie droite de celle à l'objet graphique de votre contrôle.

De cette façon, la peinture sur la peinture est plus rapide et vous ne mettez à jour que votre bufferedgraphics lorsque quelque chose de changements significatifs (c'est-à-dire des mouvements de ligne ou des modifications de texte).


1 commentaires

UHM, pas si excellent. Il suppose de mauvaises choses comme dessiner la commande totale au lieu du rectangle coupé. La plupart du temps qui ne sera pas le plus rapide. En outre, il crée manuellement un double tampon au lieu d'utiliser le contrôleur de contrôle.Doublebuffer fourni par le système, apparemment sans raison. Il est peut-être bon de sortir le code de votre gestionnaire sur votre surpeuplement, mais cet article a plus de fonctionnalités «bonus» qui ne sont pas si bonnes.



1
votes

Je dépend vraiment de ce que vous peignez. Si vous peignez quelque chose qui est repeint uniquement à la suite d'une interaction utilisateur, vous pouvez perdre vos soucis de performance et créer tous les objets graphiques ad-hoc, c'est-à-dire en cas de besoin.

Assurez-vous que vous Disposez () Tout ce dont vous avez besoin dans vos graphiques. Stylos, brosses, régions, polices. Ce sont tous des objets GDI et sont liés au système par les poignées GDI.

Si vous avez besoin de graphiques animés d'une manière ou d'une autre ou que vous modifiez dans le temps sans utilisateur, préparez-le, préparez tous vos objets graphiques devant et les réutiliser autant que vous le pouvez. La règle qui peut être appliquée ici est meilleure pour gaspiller la mémoire que millisecondes dans le dessin de chaque image de l'animation.

Un enfin, au moins pour ce post - n'oubliez pas d'utiliser un double tampon, soit automatique dans le système de contrôle .NET ou le style de rouleau-votre-bit-bitmap.

amusez-vous GDI-ING :)


0 commentaires