【问题标题】:Why the Event fires multiple times in C#?为什么事件在 C# 中多次触发?
【发布时间】:2015-12-01 03:18:11
【问题描述】:

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

我是 C# 新手,我正在使用 Windows 窗体。

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

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

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

  • UserControl2 什么都没有。

我单击“ShowUserControl2”按钮 ShowUserControl2 显示,然后单击“ShowUserControl1”按钮 ShowUserControl1 显示,然后我在 UserControl1 的 texBox 中输入文本并单击“AddRow”,添加了一个新行,它工作正常。

现在的问题是:

当我单击“ShowUserControl1”然后单击“ShowUserControl2”然后再次单击“ShowUserControl1”并输入文本然后单击“AddRow”一次,在 DataGridView 中一次添加了 2 行。单击“ShowUserControl1”3 次,单击“AddRow”一次,一次添加3 行,以此类推。

我认为 Form1 (HandleTheEvent) 中的偶数处理程序会被多次执行,因为由于在 UserControl 之间切换,我多次单击“ShowUserControl1”。如何防止多次触发偶数形式?请帮忙。 谢谢

表格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);

    }
}

【问题讨论】:

  • 您正在订阅而不是取消订阅。试试UC1.UserControl1Event -= new EventHandler(HandleTheEvent); UC1.UserControl1Event += new EventHandler(HandleTheEvent);
  • @Giorgi Nakeuri。你能告诉我把你提供的这个代码放在哪里吗?谢谢。

标签: c# winforms


【解决方案1】:

控件是创建的,但每次调用ShowUserControl1_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);
}

【讨论】:

  • @Jeroen van Langen。你的工作就像一个魔术:)。但是我有两个问题:首先,我可以在表单加载而不是构造函数中绑定事件吗?因为表单加载也有效。第二个问题:既然在Form1的构造函数中已经确定了事件,为什么还要检查是否分配了事件。请给我建议。谢谢
  • @naouf,(1)您可以在任何地方绑定事件,但您应该只绑定它。我喜欢在构造函数中绑定它们,因为我确定它只被称为。 (2) 您想要实现的一件事是重用您的代码。这次你使用这个事件,下次你可能不想使用那个事件。 (例如;您并不总是在每个控件上处理 mousedown 事件) 如果您没有将处理程序绑定到事件,那么当您触发/引发/时,您将得到一个 NullReferenceException叫它。那是因为您将 NULL 指针称为委托。
  • @Jeroen van Langen。解释得很好,非常感谢。
猜你喜欢
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-05
  • 1970-01-01
相关资源
最近更新 更多