【问题标题】:Can't call event from button无法从按钮调用事件
【发布时间】:2013-10-01 21:02:12
【问题描述】:

我有三个不同的事件:

form_load
button_click
pnlTiles_Paint

我的按钮点击事件:

private void btnUpdate_Click(object sender, EventArgs e)
{
    pnlTiles.Paint += pnlTiles_Paint;
}

我的 form_load 事件:

private void frmMain_Load(object sender, EventArgs e)
{
    pnlTiles.Paint += pnlTiles_Paint;
}

现在我的问题是,当我在 form_load 中使用它时会调用该事件,但是当我在按钮事件中使用它时;它只是跳过了事件,我在调试按钮单击时尝试进入事件。但是我在试图弄清楚为什么没有从按钮调用事件方面没有取得任何进展。

【问题讨论】:

  • 这些语句不调用事件——它们订阅事件。那是非常不同的。
  • 因此,只有当您订阅的 Paint 事件被触发时,您的处理程序才会被调用。
  • 回复:"I have three different events" - 不,您有三个不同的事件处理程序
  • 是的,如果可能的话,您最好使用 Paint 中的代码创建一个单独的函数,然后从 Load 和 Click 事件中调用该函数。在您的代码中,您实际上将 Panel 的 Paint 事件订阅到 pnlTiles_Paint。而且我认为当表单自己绘制时会触发 Paint 事件(面板也必须自己绘制)。
  • 这并不能解释为什么它在加载事件而不是按钮事件中起作用

标签: c# winforms events


【解决方案1】:

正如其他人指出的那样,pnlTiles.Paint += pnlTiles_Paint; 表示您正在订阅控件pnlTiles 上的Paint 事件。这意味着每次pnlTiles 引发Paint 事件时,都会调用pnlTiles_Paint 指定的方法。是什么导致Paint 被解雇?根据msdn

重绘控件时引发 Paint 事件。它将 PaintEventArgs 的一个实例传递给处理 Paint 事件的方法。

所以可能发生的事情是pnlTiles 在主窗体引发Load 事件之后引发Paint 事件(因为这是第一次在屏幕上绘制pnlTiles),这就是为什么你的处理程序最终被调用。

但是,单击按钮不会导致重绘 pnlTiles 并引发 Paint 事件,因此不会调用您的处理程序。

如果由于某种原因,在您将处理程序连接到Button's 单击处理程序后,需要重新绘制pnlTilespnlTiles_Paint 将被调用。您可以通过在订阅pnlTile's Paint 事件后在Button's 点击处理程序中调用pnlTiles.Invalidate() 来测试这一点。

private void btnUpdate_Click(object sender, EventArgs e)
{
    pnlTiles.Paint += pnlTiles_Paint;
    pnlTiles.Invalidate();
}

由于您对事件的基础知识有些模糊,因此可能值得阅读以下文章:

Jon Skeet - Events

MSDN - Events

另外,请务必阅读 cgijbels 对此帖子的评论,即不要多次订阅同一个事件。

【讨论】:

  • 不要将pnlTiles_Paint方法订阅到btnUpdate_Click方法中的Paint事件,因为每次点击按钮都会添加另一个订阅Paint 事件,不管它是否是相同的方法,你的pnlTiles_Paint 方法将在同一个Paint 事件中运行多次,你点击按钮的次数越多,速度就越慢。所以只订阅一次,或者如果你真的需要在点击按钮时订阅,那么至少在再次订阅之前取消订阅。
  • 当然,这是个好建议。我只是在回答有关某些特定行为的问题,因此我认为谈论订阅事件的注意事项并不重要。
猜你喜欢
  • 1970-01-01
  • 2021-10-16
  • 1970-01-01
  • 2012-08-17
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
相关资源
最近更新 更多