代码之家  ›  专栏  ›  技术社区  ›  Steve Dignan

如何避免将事件引发到关闭的窗体?

  •  3
  • Steve Dignan  · 技术社区  · 16 年前

    我在处理一个事件被提升到封闭形式并希望得到一些帮助的情况时遇到了困难。

    方案(参考以下代码):

    1. Form1 打开 Form2
    2. 形式1 订阅上的事件 形式2 (让我们称之为活动) FormAction )
    3. 形式1 是封闭的 形式2 仍然开放
    4. 形式2 扬起 形式动作 事件

    Form1.form2_FormAction 为什么 this 返回对的引用 形式1 但是 button1.Parent 收益率 null ?他们不应该都返回相同的引用吗?

    如果我们省略第3步,两个步骤 按钮1 返回相同的引用。

    这是我使用的代码…

    形式1:

    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." );
        }
    }
    

    理想情况下,我希望避免将事件引发到已关闭/已处理的表单(我不确定是否可能),或者在调用者中找到一种干净的处理方法(在本例中, 形式1 )

    感谢您的帮助。

    2 回复  |  直到 16 年前
        1
  •  3
  •   MusiGenesis    16 年前

    一个简单的解决方案是使用需要所有者的覆盖来显示Form2的实例:

    form2.Show(this);
    

    这将确保在关闭Form1时关闭Form2。不管怎样,在多表单应用程序中,这通常是一个好的实践,这样您就不会有任何无主的表单漂浮在周围。

    更新: 事件模型只是处理表单之间通信的一种方法。在您的情况下,它并不真正适合,因为接收事件的表单可以关闭,而不会引发事件的表单意识到它。

    另一种方法是用一个构造函数编写form2,该构造函数将form1的实例作为参数(该参数将保存为 _Receiver 或者别的什么)。在检查接收器是否已被释放后,Form2将调用Form1中定义的方法,而不是引发事件:

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

    如果您的form1实例仍然存在,则将调用它的方法;如果关闭并释放了它,则不会调用它的方法。由于Form2仍然存在,您还可以将接收器设置为公共财产,并随时将其“所有者”设置为其他Form1。

        2
  •  4
  •   ChrisF    16 年前

    当你靠近 form1 您应该取消订阅活动:

    form2.FormAction -= form2_FormAction;