2010-04-20 65 views
3

我在处理事件被提升为封闭形式并希望得到一些帮助的场景时遇到了问题。如何避免将事件提升为封闭形式?

方案(请参阅下面的代码以供参考):

  1. Form1打开Form2
  2. Form1订阅了一个事件上Form2(姑且称之为事件FormAction
  3. Form1被关闭,Form2遗体打开
  4. Form2引发FormAction事件

Form1.form2_FormAction,为什么this返回Form1button1.Parent回报null参考?他们不应该都返回相同的参考?

如果我们要省略步骤3,则thisbutton1.Parent都会返回相同的参考。

下面是我使用的代码...

Form1中:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click (object sender , EventArgs e) 
    { 
     // Create instance of Form2 and subscribe to the FormAction event 
     var form2 = new Form2(); 
     form2.FormAction += form2_FormAction; 
     form2.Show(); 
    } 

    private void form2_FormAction (object o) 
    { 
     // Always returns reference to Form1 
     var form = this; 

     // If Form1 is open, button1.Parent is equal to form/this 
     // If Form1 is closed, button1.Parent is null 
     var parent = button1.Parent; 
    } 
} 

窗体2:

public partial class Form2 : Form 
{ 
    public Form2() 
    { 
     InitializeComponent(); 
    } 

    public delegate void FormActionHandler (object o); 
    public event FormActionHandler FormAction = delegate { }; 

    private void button1_Click (object sender , EventArgs e) 
    { 
     FormAction("Button clicked."); 
    } 
} 

理想情况下,我想,以避免引发事件关闭/处置形式(我不知道是可能的)还是找到一个干净的方式来处理调用者(在这种情况下,Form1)。

任何帮助表示赞赏。

回答

3

简单的解决办法是使用需要一个业主的覆盖,以显示你的窗体2的实例:

form2.Show(this); 

这将确保form1关闭时form2已关闭。无论如何,在一个多形式的应用程序中,这是一个很好的练习,所以你没有任何无主人的形式。

更新:事件模型只是处理表单之间通信的一种方式。在你的情况下,它不是很合适,因为接收事件的表单可以在没有提高事件意识的表单的情况下关闭。

另一种方法是使用包含Form1实例作为参数的构造函数编写Form2(它将被保存为表单级成员,如_Receiver或其他)。相反,引发事件的,将窗体2如果_Receiver已经被布置检查,看后调用Form1中定义的方法:

if (!_Receiver.IsDisposed) 
{ 
    _Receiver.SomeMethod("some method"); 
} 

如果你的Form1的实例是仍然存在,其方法将被调用;如果已关闭并处置,则不会调用其方法。由于Form2仍在,您还可以将_Receiver设置为公共属性,并随时将其“所有者”设置为其他Form1。

+0

该应用程序的设计允许子窗体在父窗体关闭后保持打开状态。不幸的是,我无法改变设计。 – 2010-04-20 14:33:09

4

当您关闭form1你应该从事件退订:

form2.FormAction -= form2_FormAction; 
+0

form2的范围不允许这样做。 – 2010-04-20 14:28:29

+0

@Steve - 那么你将不得不扩展'form2'的范围,以便它可以。除非您退订该事件,否则您的处理程序将被调用。 – ChrisF 2010-04-20 14:32:15

+0

为什么你不能改变范围?你想打开多个Form2吗? – tanascius 2010-04-20 14:32:19