即使被调用一次,方法也会多次执行

时间:2012-03-10 11:27:02

标签: c#

我正在做一个包含动态控件创建和从WinForm中删除的项目, 所以我决定将这一部分放在一个小型测试项目上。 测试项目有两个文件Form1.cs和NewControls.cs。每当用户单击表单上已有的“添加”按钮时,此程序就会创建其他按钮。单击该按钮时会删除新创建的按钮(自我删除按钮)。删除按钮后,其他按钮的名称,文本及其位置也会根据局部变量(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);
    }
}

程序几乎按预期工作。问题是我在RemoveButton()中的form1.cs中使用的MessageBox多次触发(而不是一次),这意味着整个方法被执行多次。实际上我粘贴了MessageBox进行调试(排序)。

因为我无法像“Form1.ActiveForm.Controls.Add(newButton);”那样调试应用程序。语句执行,调试器抛出NullReferenceException,因为调试时没有活动表单。 我知道这就像一个奖金问题,但我想把它放在那里。我是一个初学者,无法通过这两个问题找到方法。第一个问题对我的原始项目非常重要,因为当添加许多控件时它会引起问题。

4 个答案:

答案 0 :(得分:2)

我认为这是因为你从Form1.cs和NewControl类的构造函数中调用PlaceControl,因为你说newButton.Click += new EventHandler(Form1.RemoveButton);
您正在添加EventHandlers,因此可以有更多它们 因此,当您多次调用placeControl时,我认为您有多个事件处理程序。

答案 1 :(得分:1)

可能还没有RemoveButton删除EventHandler。 (我最近一直在java工作,所以我的术语对于C#来说可能有些偏差。)建议:当你需要时将控制可见性设置为true,否则设置为false而不是添加和删除。

答案 2 :(得分:1)

每次删除按钮时,您都会检查现有的控件列表,然后调用“PlaceControl”,它会附加另一个处理程序。

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

RemoveButton删除上面的代码块,您会看到动态添加的按钮每次只触发一次事件。

答案 3 :(得分:1)

在您的RemoveButton事件中,您循环每个按钮并再次调用PlaceControl 唯一的原因是重新定位其余控件 我认为调用一个只做这项工作的单独方法会更好。

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

这样可以防止乱七八糟地添加事件处理程序