Need a hand

  • Thread starter Justin Lazanowski
  • Start date
J

Justin Lazanowski

I have a form that programmatticly creates 5 labels. Then programatticly
should dispose them, when this happens when it gets down to two lables left
it says that I get a null ref exception.. and I don't know why.

BTW if I check for null it leaves the two labels on my page

Can anyone explain this?

I have included the source code for this very simple test
<code>
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace ControlProblem

{

/// <summary>

/// Summary description for Form1.

/// </summary>

public class Form1 : System.Windows.Forms.Form

{

private System.Windows.Forms.Button button1;

private System.Windows.Forms.Button button2;

private System.Windows.Forms.Panel panel1;

/// <summary>

/// Required designer variable.

/// </summary>

private System.ComponentModel.Container components = null;

public Form1()

{

//

// Required for Windows Form Designer support

//

InitializeComponent();

//

// TODO: Add any constructor code after InitializeComponent call

//

}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.button1 = new System.Windows.Forms.Button();

this.button2 = new System.Windows.Forms.Button();

this.panel1 = new System.Windows.Forms.Panel();

this.SuspendLayout();

//

// button1

//

this.button1.Location = new System.Drawing.Point(48, 296);

this.button1.Name = "button1";

this.button1.Size = new System.Drawing.Size(96, 23);

this.button1.TabIndex = 0;

this.button1.Text = "Create Controls";

this.button1.Click += new System.EventHandler(this.button1_Click);

//

// button2

//

this.button2.Location = new System.Drawing.Point(248, 296);

this.button2.Name = "button2";

this.button2.RightToLeft = System.Windows.Forms.RightToLeft.No;

this.button2.Size = new System.Drawing.Size(112, 23);

this.button2.TabIndex = 1;

this.button2.Text = "Dispose Controls";

this.button2.Click += new System.EventHandler(this.button2_Click);

//

// panel1

//

this.panel1.Location = new System.Drawing.Point(16, 16);

this.panel1.Name = "panel1";

this.panel1.Size = new System.Drawing.Size(368, 192);

this.panel1.TabIndex = 2;

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(392, 341);

this.Controls.Add(this.panel1);

this.Controls.Add(this.button2);

this.Controls.Add(this.button1);

this.Name = "Form1";

this.Text = "Form1";

this.ResumeLayout(false);

}

#endregion

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Application.Run(new Form1());

}

private void createLabels()

{

int labelLoc = 0;

for(int i=0; i<5; i++)

{

labelLoc += 30;

Label lblDescriptor;

lblDescriptor = new Label();

lblDescriptor.ForeColor = Color.SaddleBrown;

lblDescriptor.Location = new System.Drawing.Point(10 , labelLoc);

lblDescriptor.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;

lblDescriptor.Name = "lbl" + i.ToString();

lblDescriptor.Size = new System.Drawing.Size(100, 21);

lblDescriptor.Text = "Test Label 1 " + i.ToString();

this.panel1.Controls.Add(lblDescriptor);

}


}

private void button1_Click(object sender, System.EventArgs e)

{

createLabels();

}

private void button2_Click(object sender, System.EventArgs e)

{

foreach(Control c in this.panel1.Controls)

{

c.Dispose();

}

}

}

}

</code>
 
S

sdbillsfan

You're disposing of objects in the collection so you can't enumerate
through them since they'll be removed from the collection when you do
dispose them. That's why it works for the first 3 but fails on the last
2 (first iteration is index 0 then it's removed so now you really only
have 4 items in your collection, next iteration is index 1 then it's
removed so now you only have 3 items in your collection, etc). In order
to do what you want to do you'll have to start at the end and move
backward.

for(int x = panel1.Controls.Count - 1; x >= 0; x--)
{
panel1.Controls[x].Dispose();
}
 
M

Matt

Justin said:
I have a form that programmatticly creates 5 labels. Then programatticly
should dispose them, when this happens when it gets down to two lables left
it says that I get a null ref exception.. and I don't know why.

BTW if I check for null it leaves the two labels on my page

It does worse than that, it crashes. You just aren't always seeing the
exception. I'm honestly not sure what is going on here, except that
what I *think* happens is that when you dispose of the control from
within the panel control's array, it tells its parent (the panel) to
remove it from the array. Thus, the array changes within the foreach
loop and bad things happen.

Try this:

private void button2_Click(object sender, System.EventArgs e)

{
ArrayList al = new ArrayList();

foreach(Control c in this.panel1.Controls)
{
al.Add( c );
}

foreach( Object o in al )
{
Control c = (Control)o;
c.Dispose();
}
}

It seemed to work ok for me.

Matt
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top