La suppression de créer dynamiquement des contrôles en C#
J'ai un programme qui ajoute une série de "blips" à un graphe:
PictureBox blip = new PictureBox();
blip.Location = new Point(blipHours, blipAltitude);
blip.Size = new Size(6, 6);
blip.BackColor = System.Drawing.Color.Lime;
blip.Text = "";
blip.Name = callsign;
this.Controls.Add(blip);
this.Controls.SetChildIndex(blip, 0);
-
Comment puis-je avoir un bouton pour effacer tous les "blips" qui ont été créés avec ce code?
-
Est-il un moyen de changer l'éclat de la couleur d'arrière-plan lorsque son nom est égal à un certain
callsign
? Chaque spot est associée à une sélection dans unListBox
, et je voudrais changer l'éclat de la couleur lorsque l'utilisateur sélectionne.
Vous devez vous connecter pour publier un commentaire.
Tout le monde, c'est d'oublier un très détail important: vous devez Éliminer() le contrôle ou il fuira jamais:
Je vais mettre un peu plus l'accent sur la jamais clause, beaucoup de clameur ce sujet dans les commentaires, la classe de Contrôle ne se comporte pas comme les autres .NET de la classe. Un Contrôle est maintenu en vie par ses
Handle
de la propriété. Qui stocke le natif de Windows poignée. Tant que la fenêtre native existe, l'objet de Contrôle ne peut pas être détruit.Cela nécessite de l'objet à être maintenu artificiellement en vie lorsque vous utilisez Clear() ou de Supprimer() et supprimer le contrôle de son parent. Winforms utilise le soi-disant "parking de la fenêtre", comme l'hôte de ces contrôles. C'est un natif de la fenêtre comme n'importe quel autre, il est tout simplement pas visible. Son travail est d'être le parent de ces orphelins contrôles.
Le parking de la fenêtre permet beaucoup de trucs qui sont normalement très difficile à faire dans Windows. Vous pouvez par exemple activer la propriété ShowInTaskbar sur et en dehors au moment de l'exécution. Une propriété d'une fenêtre qui ne peut normalement être spécifié lors de la création de la fenêtre (WS_EX_APPWINDOW style, spécifié dans le CreateWindowEx() l'appel). Winforms pouvez le faire même après que vous avez créé la fenêtre en déplaçant le contrôle de la forme sur le parking de la fenêtre, en détruisant la fenêtre, la création de nouveau et le réglage des commandes dos. Neat.
Mais avec la pas-si-soigné hangup c'est le thème de cette réponse, si vous supprimez le contrôle et la ne pas appeler sa méthode dispose() puis il va continuer à survivre sur le parking de la fenêtre. Pour toujours. Une véritable fuite. Rien que le garbage collector peut faire à ce sujet, il voit une référence valide à l'objet. Une jolie violation flagrante de la IDisposable contrat, l'appelant Dispose() est facultative, mais il est pas pour la classe de Contrôle.
Heureusement, un tel bug est assez facile à diagnostiquer, il ne nécessite pas d'outillage spécial, vous pouvez voir la fuite dans le Gestionnaire des Tâches de l'onglet Processus. Ajouter l'UTILISATEUR "Objets" de la colonne.
Dispose
automatiquement supprimer le contrôle à partir du conteneur de contrôle de collection (c'est pourquoi la liste d'itérations vers le bas). Btw, vous avez répondu, c'est même mieux ici: stackoverflow.com/questions/1969705/... 😉Vous voudrez peut-être ajouter de l'éclat à une Liste et ensuite, lorsque l'utilisateur clique sur le bouton "Effacer", juste itérer sur la liste, supprimez le spot de la collection de Contrôles, puis effacer la liste.
En termes de modification de la couleur d'arrière-plan, pourquoi ne pas simplement utiliser une instruction if?
Cela va supprimer tous les contrôles PictureBox à partir du conteneur particulier (je suppose un graphique dans votre cas).
Il semble Hans Passant oublié un détail très important, trop (ou peut-être qu'il était juste en ajoutant à la les réponses existantes, de ne pas présenter une réponse). En tout cas, voici ce que j'avais à faire les deux à invisiblize et jeter mes contrôles dynamiques: