5

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?

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
David
  • 5,356
  • 2
  • 26
  • 39

3 Answers3

4

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
  • 7,905
  • 3
  • 28
  • 40
  • Thanks, where did you find the snippet of Control.Dispose? – David Nov 18 '09 at 16:47
  • 2
    @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 Nov 18 '09 at 18:11
2

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
  • 7,464
  • 1
  • 31
  • 52
  • 2
    From my experiment, disposing a tabpage removes it from the TabControl – David Nov 18 '09 at 16:28
  • That's surprising! I wasn't aware of that. – Marty Nov 18 '09 at 16:29
  • Even if it is, you shouldn't use at as a code pattern, it can lead to bugs with other Disposable objects. – Massimiliano Nov 18 '09 at 16:33
  • @Marty I wasn't aware of that either before I created a sample project and tried it out :). – David Nov 18 '09 at 16:42
  • 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 Nov 18 '09 at 18:17
2

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().

Massimiliano
  • 16,770
  • 10
  • 69
  • 112
  • Isn't this the case for all controls? That is why the IsDisposed property exists... – Philip Wallace Nov 18 '09 at 16:41
  • 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. – Massimiliano Nov 18 '09 at 17:06