views:

401

answers:

3

I am working on a windows form that has a TabControl named tabDocuments. I came across this piece of code that removes all pages from the TabControl.

for (int i = tabDocuments.TabPages.Count - 1; i > -1; i--) {
    tabDocuments.TabPages[i].Dispose();
}
    tabDocuments.TabPages.Clear();

The person who wrote this code has already left a while ago. I am trying to understand why the code is calling Clear() after disposing each of the tabPages (looks un-necessary to me). Can anyone please explain to me why? Or is calling Clear() extra?

A: 

Calling Dispose() on each of the tab pages does not actually remove them from the TabPages collection, it simply disposes them. The call to Clear() is what removes them from the collection. If you don't call Clear() they will still be there, and bad things will likely happen because you will end up trying to use them after they have been disposed.

Marty Dill
From my experiment, disposing a tabpage removes it from the TabControl
David
That's surprising! I wasn't aware of that.
Marty Dill
Even if it is, you shouldn't use at as a code pattern, it can lead to bugs with other Disposable objects.
Yacoder
@Marty - your answer is incorrect. Check using reflector.
Philip Wallace
@Marty I wasn't aware of that either before I created a sample project and tried it out :).
David
You're answer makes sense. Based on what the documentation says the methods will do. However, since the Dispose method has additional undocumented functionality (not that its wrong, just undocumented) the clear call is not completely necessary, but in my opinion still good practice.
rocka
A: 

First remove a Tab from the collection, then Dispose(). Never Dispose() something that is still in use, as it will cause exceptions and strange behavior.

Also, ensure that no one else have references to the tabs, otherwise those references will become invalid on Dispose().

Yacoder
Isn't this the case for all controls? That is why the IsDisposed property exists...
Philip Wallace
Usually you don't Dispose controls, they exist throughout the app and they don't keep critical unmanaged resources. You may want to dispose Forms used as one-time dialogs. Then the Form will dispose its controls.
Yacoder
A: 

This snippet is from Control.Dispose:

        if (this.parent != null)
        {
            this.parent.Controls.Remove(this);
        }

Therefore you just have to call Dispose, not Clear.

Philip Wallace
Thanks, where did you find the snippet of Control.Dispose?
David
Reflector - http://www.red-gate.com/products/reflector/
Philip Wallace
@Xaero, Although, you are correct about the control removing itself from its parent. You only happen to know that by having disassembled the assembly. No where in the public documentation for the method does it say it removes itself from it parent. This functionality could be changed in future version of the framework. I know the calling assembly can target a specific version of the.NET framework. However, wouldn't it be better practice to call the method as they are intended based on the public documentation (even if it's not necessary).
rocka