2013-03-01 16 views
5

powiedzmy mam jakiś składnik takiego:Kto jest właścicielem elementów sterujących?

class SomeForm : Form 
{ 
    private Control example; 

    public void Stuff() 
    { 
     this.example = new ComboBox(); 
     // ... 
     this.Controls.Add(example); 
    } 

    public void OtherStuff() 
    { 
     this.Controls.Remove(example); 
    } 
} 

kto jest odpowiedzialny za wywołanie Dispose sprawie kontroli przykład? Czy usunięcie go z this.Controls powoduje jego usunięcie? Czy może to nieszczelne klamki okien wspierające kontrole?

(Dla porównania, to pytam, bo nie widzę gdzie Forms Designer Windows generuje kod, aby zadzwonić Dispose na dzieci formą'S)

Odpowiedz

5

Form.Dispose() będzie dysponować elementami sterującymi w ramach kolekcji Controls. Usunięcie kontroli z Controls będzie wymagało samodzielnego rozporządzania kontrolą.

3

Gdy formularz zawierający tej kontroli jest umieszczony, że wszystkie kontrole przechowywane w obiekcie Controls zostaną usunięte. Nie trzeba usuwać formantu niestandardowego z kolekcji. Tylko upewnij się, że formularz zawierający jest usuwany.

Jeśli usuniesz kontrolkę z kolekcji, kontrola ta w końcu wypadnie poza zasięgiem i będzie nieczytelna w przypadku usuwania śmieci. Po uruchomieniu GC wywoła on finalizator/destruktor, który w przypadku klasy Form po prostu wywoła metodę Dispose. W związku z tym na tym polega zła praktyka. Powinieneś zawsze upewnić się, że masz deterministycznie (ręcznie) metodę Dispose na klasach implementujących interfejs IDisposable, gdy tylko skończysz z nimi pracować.

+0

Więc twierdzisz, że kontrola zostanie ujawniona? – Servy

+0

Absolutnie nie. Jak już powiedziałem w mojej odpowiedzi, gdy formularz zawierający zostanie usunięty, wszystkie kontrole w obrębie właściwości Controls zostaną usunięte. Wszystko, co musisz zrobić, to upewnić się, że instancja zawierająca formularz została usunięta. –

+0

Sterowanie ** nie jest ** w kolekcji 'Controls', ponieważ usunął ją z tej kolekcji przed pozbyciem się rodzica. Wygląda na to, że przegapiłeś cały punkt pytania. – Servy

0

Zawsze iść do źródła wątpliwości:

Form.Dispose wygląda trochę tak:

protected override void Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
     ... lots and lots of weird optimized checks ... 
     base.Dispose(disposing); 

Ok ... Form jest ContainerControl tak:

ContainerControl.Dispose:

protected override void Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
     this.activeControl = null; 
    } 
    base.Dispose(disposing); 
    this.focusedControl = null; 
    this.unvalidatedControl = null; 
} 

Grrr * ... ok, ContainerControl jest Control:

Control.Dispose:

protected override void Dispose(bool disposing) 
{ 
    ... a whole lot of resource reclaiming/funky code ... 
    ControlCollection controls = (ControlCollection) 
      this.Properties.GetObject(PropControlsCollection); 
    if (controls != null) 
    { 
     for (int i = 0; i < controls.Count; i++) 
     { 
       Control control = controls[i]; 
       control.parent = null; 
       control.Dispose(); 
     } 
     this.Properties.SetObject(PropControlsCollection, null); 
     } 
     base.Dispose(disposing); 

Więc tak; dzwonienie pod numer Dispose na formularzu spowoduje usunięcie zawartych w nim formantów.

+0

Nie o to pyta się jednak pytanie; pyta się, czy tylko elementy kontrolne w zbiorze "Kontroli" są usuwane, gdy formularz jest utylizowany, co oznacza, że ​​jeśli usunie kontrolę (co robi) jest teraz odpowiedzialny za jej usunięcie, czy jest jakiś inny mechanizm (np. kontrola przy wyjmowaniu go z kolekcji), która uniemożliwia mu pozbycie się go. – Servy

+1

Erm, nie każdy ma dostęp do kodu źródłowego środowiska .NET. –

+0

@Servy: Interesuje mnie zarówno –

Powiązane problemy