为什么事件在C#中多次激发?

为什么事件在C#中多次激发?,c#,winforms,C#,Winforms,我在这里检查了类似的问题,但答案与我的问题无关 我是C#新手,我使用的是windows窗体 如屏幕截图所示,我有form1、UserControl1和UserControl2 Form1有2个按钮(ShowUserControl1和ShowUserControl2)和DataGridView UserControl1有按钮“AddRow”和文本框 UserControl2什么都没有 我单击“ShowUserControl2”按钮ShowUserControl2 show up,然后单击“S

我在这里检查了类似的问题,但答案与我的问题无关

我是C#新手,我使用的是windows窗体

如屏幕截图所示,我有form1、UserControl1和UserControl2

  • Form1有2个按钮(ShowUserControl1和ShowUserControl2)和DataGridView

  • UserControl1有按钮“AddRow”和文本框

  • UserControl2什么都没有

我单击“ShowUserControl2”按钮ShowUserControl2 show up,然后单击“ShowUserControl1”按钮ShowUserControl1 show up,然后在UserControl1的文本框中输入文本,然后单击“AddRow”添加新行,效果良好

现在的问题是:

当我单击“ShowUserControl1”然后单击“ShowUserControl2”然后再次单击“ShowUserControl1”并输入文本然后单击“AddRow”一次时,在DataGridView中一次添加两行。点击“ShowUserControl1”三次,点击“AddRow”一次,一次添加三行,依此类推

我认为Form1(HandleTheEvent)中的均衡器会被执行多次,因为我多次单击“ShowUserControl1”,这是在UserControls之间切换的结果。如何防止偶数形式多次开火?请帮忙。 多谢各位

表格1:

public partial class Form1 : Form
{

    UserControl1 UC1 = new UserControl1();
    UserControl2 UC2 = new UserControl2();

    public Form1()
    {
        InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        //add user controls when form loads
        Controls.Add(UC1);
        Controls.Add(UC2);
    }


    private void ShowUC(Control value)   // Show/hide User Controls
    {
        UC1.Visible = false;
        UC2.Visible = false;

        value.Visible = true;

     }


    public void HandleTheEvent(object sender, EventArgs e) //deal with the event
    { 

        dataGridView1.Rows.Add(1, UC1.ReturnData, 3);

    }


    private void ShowUserControl1_Click(object sender, EventArgs e)
    {


        ShowUC(UC1); //show User Control1
        UC1.UserControl1Event += new EventHandler(HandleTheEvent);


    }

    private void ShowUserControl2_Click(object sender, EventArgs e)
    {
        ShowUC(UC2); //show User Control2
    }
}
用户控制1:

public partial class UserControl1 : UserControl
{

    public event EventHandler UserControl1Event;

    public UserControl1()
    {
        InitializeComponent();
    }


    public string ReturnData 
    {
        get { return textBox1.Text; }

    }
    private void AddRow_Click(object sender, EventArgs e)
    {
        UserControl1Event(this, e);

    }
}

控件是一个一个地创建的,但每次调用
ShowUserControl1\u Click
,都会再次绑定事件。这意味着当引发/调用
UserControl1Event
事件时。调用多次
HandleTheEvent
。事件是处理程序的列表

private void ShowUserControl1_Click(object sender, EventArgs e)
{


    ShowUC(UC1); //show User Control1


    UC1.UserControl1Event += new EventHandler(HandleTheEvent);


}
您应该在构造函数中绑定事件:

public partial class Form1 : Form
{

    UserControl1 UC1 = new UserControl1();
    UserControl2 UC2 = new UserControl2();

    public Form1()
    {
        InitializeComponent();

        UC1.UserControl1Event += new EventHandler(HandleTheEvent);
    }

不要忘了检查是否在此处分配了
UserControl1Event

private void AddRow_Click(object sender, EventArgs e)
{
    // here!
    if(UserControl1Event != null)
        UserControl1Event(this, e);
}

您正在订阅,而不是取消订阅。尝试
UC1.UserControl1Event-=neweventhandler(HandleTheEvent);UC1.UserControl1Event+=新事件处理程序(HandleTheEvent)@Giorgi Nakeuri。你能告诉我你提供的代码放在哪里吗?谢谢你,杰伦·范兰根。你的工作很神奇:)。但我有两个问题:首先,我可以用表单加载而不是构造函数绑定事件吗?因为表单加载也起作用。第二个问题:为什么我们必须检查事件是否被分配,因为它已经在Form1的构造函数中被确定分配了。请告诉我。感谢you@naouf,(1)您可以在任何地方绑定事件,但应仅绑定一个事件。我喜欢在构造函数中绑定这些元素,因为我确信它被称为only one。(2) 您希望实现的一件事是重用代码。这次您正在使用此事件,下次您可能不想使用该事件。(例如,并非总是在每个控件上处理mousedown事件)如果没有将处理程序绑定到事件,则在激发/引发/调用它时将得到
NullReferenceException
。这是因为您将
NULL
指针作为委托调用。@Jeroen van Langen。解释得很好,非常感谢。