2010-03-04 4 views
2

Nous rencontrons quelques problèmes avec le modèle IDisposable. Dans ce cas, il existe un contrôle utilisateur 'ControlA' avec un FlowLayoutPanel, qui contient plus de contrôles usB 'ControlB'.Disposer correctement les commandes utilisateur et les commandes enfants en C#

Lors de l'appel de Dispose (bool), je vérifie si la disposition est vraie, et si IsDisposed est faux. J'essaie ensuite de disposer explicitement chaque ControlB dans la collection Controls de FlowLayoutPanel. Toutefois, si ne boucle pas par tous les contrôles, seulement 3 de 8 ou 2 4.

Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
    if (!IsDisposed) 
    { 
     //unhook events etc. 

     foreach(ControlB ctrl in flowlayoutpanel.Controls) //<-- there 8 controls 
     ctrl.Dispose(); //<-- called 3 times only 

     flp.Controls.Clear(); 
    } 
    } 
    //make all members null 
} 

Mes quesitons sont: 1. Pourquoi est-ce qui se passe? 2. Quelles sont les meilleures pratiques et les expériences que vous avez eues avec les commandes utilisateur et les contrôles enfants? Par exemple. Désabonnez-vous les gestionnaires d'événements à tout moment, etc.

Merci!

Répondre

5

Vous n'avez pas besoin de disposer manuellement les commandes qui sont des commandes enfants de la commande en cours de mise au rebut, c'est-à-dire dans la collection Contrôles. Le contrôle parent va gérer cela automatiquement. Si vous êtes éliminé, vous devez vous désabonner des événements qui ne font pas partie de votre périmètre, c'est-à-dire des membres d'objets qui resteront en vie, car ils vous garderont également en vie, même s'ils sont éliminés. Vous n'avez pas besoin de vous désabonner des événements dans les objets qui sont également éliminés, comme les contrôles enfants.

+0

Cela a du sens. Mais pourquoi ces contrôles enfants vivent-ils encore après que Dipose a été appelé sur le contrôle parent? Comment est-ce possible? – John

+0

Les contrôles ne doivent pas rester en ligne après avoir été éliminés. Essayez d'accéder à une propriété, il devrait lancer une exception ObjectDisposedException, ou quel que soit le nom. Cependant, les * objets * sous-jacents vont vivre jusqu'à ce que toutes les références à ces objets disparaissent, c'est pourquoi il est important de se désinscrire des événements extérieurs. – OregonGhost