17

.NET 2

// dynamic textbox adding
myTextBox = new TextBox();
this.Controls.Add(myTextBox);

// ... some code, finally

// dynamic textbox removing
myTextBox.Dispose();

// this.Controls.Remove(myTextBox); ?? is this needed

Little explanation

  • Surely, if I Dispose a control I will not see it anymore, but anyway, will remain a "Nothing" in the parent controls collection?
  • need I also, like MSDN recommends, remove all handlers from the control?
serhio
  • 28,010
  • 62
  • 221
  • 374
  • 2
    Why don't you try it and see what happens? – SLaks Jan 06 '10 at 15:17
  • what could happen? if I dispose a control I will not see it anymore, but anyway, will remain "Nothing" in the parent controls collection? – serhio Jan 06 '10 at 15:21
  • 2
    Just a curiosity, why wouldn't you Remove then Dispose of it anyway? I would suggest that your code read the same as your intentions will help quite a bit. – hometoast Jan 06 '10 at 16:00
  • I'm with hometoast. It sounds like you are a C++ coder moving to C#. If you are you may want to look into how the CLR works - managed memory management is a bit different than the old manual way of doing things. What you are doing is like looking for a clutch in an automatic. It's not needed. – diadem Jan 06 '10 at 16:26
  • 1
    @hometoast: the problem is a little more complicated in reality. I add the control to a container that I am not necessarily have access to. I can dispose in a method a control, but in order to removing it from the parent collection first of all I need to access the parent. Surely, is not so complicated if `(myControl.Parent) != null` but why to repeat the same code like in the Control's Dispose method?!... – serhio Jan 06 '10 at 16:34
  • @diadem: No, dude, I am not a C++ coder :) I am pure C#, and is not very clear what you are trying to say now... what do you mean "manually"? dynamically adding controls is not at all unusual in C# nor in .NET :) – serhio Jan 06 '10 at 16:35
  • @serhio: Your explanation to hometoast explains why you did what you did - I thought you were just arbitrarily trying to call dispose on managed objects before they go out of scope, which you aren't. – diadem Jan 06 '10 at 17:40

6 Answers6

17

No, you don't.
I tried it.

You can paste the following code into LINQPad:

var form = new Form();
var b = new Button();
form.Controls.Add(b);
b.Click += delegate { b.Dispose(); };
Application.Run(form);

EDIT: The control will be removed from the form's Controls collection. To demonstrate this, replace the click handler with the following:

b.Click += delegate { b.Dispose(); MessageBox.Show(form.Controls.Count.ToString());};

It will show 0.

2nd EDIT: Control.Dispose(bool disposing) contains the following code:

                if (parent != null) { 
                    parent.Controls.Remove(this); 
                }
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • +1 Good work. Its interesting that the msdn articale kbrinley posted mentions calling Remove then Dispose. Looks like you only need Dispose. Good to know. – SwDevMan81 Jan 06 '10 at 15:39
  • yah. now, believe to MSDN, that recommends first to remove, and only then Dispose the control... – serhio Jan 06 '10 at 16:24
  • Calling `Remove` first will make your code easier to understand. However, it won't make any difference in the actual behavior. – SLaks Jan 06 '10 at 16:27
4

EDIT:

MSDN suggests that you remove the object from the Control and then call dispose when removing an object from a collection at runtime:

http://msdn.microsoft.com/en-us/library/82785s1h%28VS.80%29.aspx

// dynamic textbox adding
myTextBox = new TextBox();
this.Controls.Add(myTextBox);

// ... some code, finally

// dynamic textbox removing
this.Controls.Remove(myTextBox);

myTextBox.Dispose(); 
kbrinley
  • 3,374
  • 3
  • 20
  • 9
  • 2
    This is completely false. You should _always_ call `Dispose` manually to ensure that native resources (in the case, a window handle) are released as soon as they are no longer needed. Relying on the finalizer to call `Dispose` will cause the native resources to be released much later, when the GC runs. – SLaks Jan 06 '10 at 15:24
  • @kbrinley: Sometimes, MSDN tells general thinks that is not necessarily optimized etc etc... – serhio Jan 06 '10 at 15:32
  • I've found an MSDN article regarding this exact situation, which does indeed suggest calling Remove then Dispose. – kbrinley Jan 06 '10 at 15:32
  • @SLaks: I thought the resources were kept in memory until it was full, then the manager performs a cleanup. If that is the case, how would calling dispose be any benefit other than prematurely calling GC features? – diadem Jan 06 '10 at 16:29
  • @diadem - You are right, the resources will be kept in memory until the GC is called, howerer it will not call Dispose in the normal manor. This (http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=88e62cdf-5919-4ac7-bc33-20c06ae539ae) is a great sight for understanding the differences. Basically the GC will call the Finalizer functions of each unreferenced object when it decides to clean up. – SwDevMan81 Jan 06 '10 at 17:49
2

But looking at the answer from Mat it looks as though this behavior depends on the framework being used. I think he's suggesting that when using the compact framework some controls must be Removed and also Disposed.

So Microsoft suggesting that we always remove and then dispose kind of makes sense especially if you're moving code modules to other frameworks.

MRP

MRP
  • 21
  • 1
1

After some tests, I find out that the disposed controls are automatically removed from the parent control collection.

Controls.add(myButton); //Control.Count==4
myButton.Dispose(); //Control.Count==3

UPDATE

from the control's Dispose(bool) method:

if (this.parent != null)
{
    this.parent.Controls.Remove(this);
}
serhio
  • 28,010
  • 62
  • 221
  • 374
1

Further Information on Compact Framework 2 + VS2005 Designer may crash when removing a control which is derived from s.w.f.control, if it doesn't implement the following:

Dispose()  
{  
 if(this.parent!=null){  
  this.parent.controls.remove(this);   
 }  
 ....  
}  
Mat
  • 11
  • 1
-1

Just keep in mind that if you have some code to iterate over your controls and do something, you would get an exception if one of these controls had been disposed. Therefore, in general I would probably recommend removing the control as good practice.

hackerhasid
  • 11,699
  • 10
  • 42
  • 60
  • 2
    No, you wouldn't. `Dispose` will remove the control from the `Controls` collection. I checked. – SLaks Jan 06 '10 at 15:26
  • 1
    @hippo: apparently, the disposed controls are automatically removed from the parent control collection. – serhio Jan 06 '10 at 15:26