想象一下下面的场景:
this.SetStyle(ControlStyles.UserPaint, true);
â¦
void OpenSomeForm()
{
SomeForm sf = new SomeForm();
sf.SomeEvent += new ⦠(SomeEventOcurred);
sf.ShowDialog();
}
private void SomeEventOcurred(â¦)
{
OnePanelInThisForm.Invalidate();
}
private void OnePanelInThisForm_Paint(object sender, PaintEventArgs e)
{
DoSomeDrawing(e.Graphics);
}
不
解雇。如果我关闭并重新打开表单,它将正确地重新绘制。
我错过了什么?
更新
:澄清。(我们首先为什么不这样做)
我有一个表单。这个表单有一个覆盖绘画事件的面板。这是一个标准的WinForm。在颜料上画一个圆圈。这很管用。原来FORM_A有一个打开FORM_ab的按钮,但在执行此操作之前,它订阅FORM_ab中名为:SomeEvent的自定义事件。(见上面的示例)。所以B表可以告诉A表一些事情。
现在,FORM_B也是一个普通的WinForm。它有一个普通的按钮。在该按钮的单击事件中,它打开FORM_C。FORM_C还有一个名为SomeEvent的事件,显然FORM_B订阅了该事件。和以前一模一样。其思想是FORM_C有一个按钮,可以触发该事件,通知感兴趣的订阅者。在这种情况下,当FORM_C触发事件时,FORM_B被订阅并感兴趣。
当FORMúB收到回拨时,它所做的唯一事情是通知相关方(在本例中,FORM A)事件已被触发。
现在,即使表单C仍然是顶级表单,调用堆栈也会返回到FormA,返回到从第一个事件定义为callback的方法。
执行此代码。它所做的只是somePanel.Invalidate()(或Refresh(),相同的结果)。
该面板的PAINT方法中有一个断点,表示代码没有被调用。尽管已无效,但不会引发绘画事件。我假设发生这种情况是因为表单(因此面板)实际上由FORMB和FORMC(仍然打开)覆盖。
仅此而已。如果我关闭表单C,然后关闭表单B,表单A仍然不会引发绘制事件。我试着让激活表单的面板失效,但这并没有发生。
如果我关闭表单A并重新打开它,那么图形当然是正确的。
没有太多的代码,因为这非常简单,形式为A>B>C(fire event)->B->A->Invalidate()。