Reputation: 15
First, post so I'll keep my question short.
I added a control to my tabpage. Because of the limitation of having one variable only, but different name properties. I decided to add all my text box objects I create in a list. The text boxes are created by a loop.
Now when I remove them I understand I have to invoke the dispose method. I have to remove the control, and finally decrement the event handlers.
My question is what do these really do. I expected that my list of text boxes once removed would not exist anymore. Therefore that list should either become empty or throw an exception if I call their properties such as name, etc.
So why are these text boxes still in my list and still functioning? It's as if I never removed them. Although they're not on my form anymore it seems they're still living in the background which could mean memory leaks or slowing of the program. I would appreciate any explanation on what these methods do and why the textbox objects still exist.
Final note, I'm coming from cpp. So the way I see it once called delete on dynamically created objects, the variable shouldn't work anymore.
Also, I can add my code if required.
Edit: my code as follows
For adding to tabpage:
if (int.TryParse((sender as TextBox).Text, out int Stories))
{
Console.WriteLine(Stories); this.Stories = Stories;
string L_name = "Label_";
string T_name = "TextBox_";
int counter = 1;
int yIncr = Story_label.Size.Height + 3;//widthoftextbox+spacing
List<string> L_name_arr = new List<string>
{
L_name + counter.ToString()
};
List<string> T_name_arr = new List<string>
{
T_name + counter.ToString()
};
for (int i = 0; i < Stories; i++)
{
//create new labels and textboxes below
//have a max value.
Label L_ = new Label();
Model_Geometry_tab.Controls.Add(L_);
L_.Location = new System.Drawing.Point(Story_label.Location.X, Story_label.Location.Y + yIncr * counter);//increasing increment every iteration
L_.Name = L_name_arr[i];
L_.Size = new System.Drawing.Size(Story_label.Size.Width, Story_label.Size.Height);
L_.Text = "Story" + counter.ToString();
TextBox T_ = new System.Windows.Forms.TextBox();
//T_.BackColor = System.Drawing.SystemColors.ActiveBorder;
T_.Location = new System.Drawing.Point(Story_input.Location.X, Story_input.Location.Y + yIncr * counter);
T_.MaxLength = 1000;
T_.Name = T_name_arr[i];
T_.Size = new System.Drawing.Size(Story_input.Size.Width, Story_input.Size.Height);
T_.KeyDown += new System.Windows.Forms.KeyEventHandler(TextBox_1_KeyDown);
T_.MouseClick += new System.Windows.Forms.MouseEventHandler(textBox_other_MouseClick);
T_.MouseHover += new System.EventHandler(textBox2_MouseHover);
Story_arr.Add(T_);
Model_Geometry_tab.Controls.Add(T_);
//incr counter
counter++;
//addnewlabeltags
L_name_arr.Add(L_name + counter.ToString());
//addnewtexttags
T_name_arr.Add(T_name + counter.ToString());
}
}
else
{
MessageBox.Show("Enter an integer value please!");
}
For removing them, I use the list Story_arr;
private void button2_Click(object sender, EventArgs e)
{
if (Story_arr.Count != 0 && !a)
{
foreach (var item in Story_arr)
{
Console.WriteLine(item.Name);
item.KeyDown -= new System.Windows.Forms.KeyEventHandler(TextBox_1_KeyDown);
item.MouseClick -= new System.Windows.Forms.MouseEventHandler(textBox_other_MouseClick);
item.MouseHover -= new System.EventHandler(textBox2_MouseHover);
Model_Geometry_tab.Controls.Remove(item);
item.Dispose();
}
a = true;
}
else if (a)
{
foreach (var item in Story_arr)
{
Console.WriteLine(item.IsDisposed);
}
}
else
MessageBox.Show("It is empty list");
}
Upvotes: 0
Views: 177
Reputation: 14017
When you call IDisposable.Dispose
, it does not mean that the object is deleted. Disposing an object is intended to clean up any internal or external resources. In WinForms this specifically means cleaning up any underlying window handles etc.
In .NET managed memory, only the garbage collector will ultimately remove the object. In your specific case though the GC will never collect your removed controls, because you still have them in your list. Having them in the list means that the objects are still referenced, i.e. they are not dead. The GC will only collect dead objects.
Just manually remove the control from your list and you'll be fine. You can also listen to the Disposed
event of the control and remove it from the list in the event handler. That will automatically take care of removing any disposed control from your list.
A more advanced solution would be to not add the controls directly to your list, but to add weak references. A WeakReference
allows you to access the object, but it will not prevent garbage collection. However, I personally would prefere to dereference the object manually, since this is more straightforward and less error prone.
Upvotes: 1