Master Chief
Master Chief

Reputation: 2541

Method executing several times even though it is called once

I am doing a project which includes dynamic controls creation and removal from the WinForm, So I decided to that part on a small test project. Test project has two files Form1.cs and NewControls.cs. This program creates additional buttons whenever user clicks an Add button already on the form.And removes the newly created button when it is clicked (self removal button). Also after removal of button other button's Name, Text and their position are changed according to a local variable (controlIndex).

Form1.cs

public partial class Form1 : Form
{
    static List<NewControl> newControlsList = new List<NewControl>();
    public Form1()
    {
        InitializeComponent();
    }

    private void Add_Click(object sender, EventArgs e)
    {
        newControlsList.Add(new NewControl(newControlsList.Count));
    }

    public static void RemoveButton(object sender, EventArgs e)
    {
        NewControl tempNewControl = (NewControl)(sender as Button).Tag;
        tempNewControl.RemoveControl();
        newControlsList.Remove(tempNewControl);
        MessageBox.Show("Removed!");
        foreach (NewControl tempcontrol in newControlsList)
        {
            tempcontrol.controlIndex = newControlsList.IndexOf(tempcontrol);
            tempcontrol.PlaceControl();
        }
    }
}

NewControl.cs

class NewControl
{
    public int controlIndex = 0;
    Button newButton = new Button();

    public NewControl(int index)
    {
        controlIndex = index;
        PlaceControl();
    }

    public void RemoveControl()
    {
        newButton.Dispose();
        Form1.ActiveForm.Controls.Remove(newButton);
    }

    public void PlaceControl()
    {
        newButton.Tag = this;
        newButton.Name = "btn" + controlIndex.ToString("D2");
        newButton.Text = "btn" + controlIndex.ToString("D2");
        newButton.Size = new Size(100, 20);
        newButton.Left = controlIndex * 100;
        Form1.ActiveForm.Controls.Add(newButton);
        newButton.Click += new EventHandler(Form1.RemoveButton);
    }
}

Program works nearly as expected. Problem is the MessageBox which I used in form1.cs in RemoveButton() fires many time (as opposed to just one time), which implies whole method being executed several times. Actually I pasted that MessageBox for debugging (sort of).

Since I cannot debug the application as when "Form1.ActiveForm.Controls.Add(newButton);" statement is executed, debugger Throws NullReferenceException, as there is not an active form while debugging. I know that's like a bonus question but I thought to just put it there. I am a beginner and can't see the way through both the problems. 1st problem is really important for my original project as it will cause problem when many controls are added.

Upvotes: 2

Views: 827

Answers (4)

Steve
Steve

Reputation: 216243

In your RemoveButton event you loop on each button and call again PlaceControl.
The only reason is to reposition the remainder controls.
I think it's better a call to a separate method that do only this work.

public void RepositionControl() 
{ 
    newButton.Left = controlIndex * 100; 
} 

this will prevent to mess with event handlers added more than one time

Upvotes: 1

Tung
Tung

Reputation: 5434

Everytime a button is removed you go over your existing list of controls, and you call "PlaceControl", which attaches yet another handler.

foreach (NewControl tempcontrol in newControlsList)
{
    tempcontrol.controlIndex = newControlsList.IndexOf(tempcontrol);
    tempcontrol.PlaceControl(); 
}

Remove the above code block from RemoveButton, and you will see that your dynamically added buttons will each only trigger the event once.

Upvotes: 1

jacknad
jacknad

Reputation: 13739

Probably the EventHandler hasn't been removed by RemoveButton. (I've been working in java most recently so my terms might be a little off for C#.) Suggestion: set control visibility to true when you want it and false otherwise rather than adding and removing.

Upvotes: 1

11684
11684

Reputation: 7507

I think it is because you call PlaceControl from Form1.cs AND in the constructor of the NewControl class, Because you say newButton.Click += new EventHandler(Form1.RemoveButton);.
You are adding EventHandlers, so there can be more of them.
So when you call placeControl multiple times, you've got multiple event handlers, i think.

Upvotes: 2

Related Questions