关闭表单后启用按钮

时间:2013-03-18 08:45:44

标签: c++ .net winforms

我想在关闭第二个表单时从主表单启用一个按钮。我已经阅读了一些关于调用的内容,但对此并不了解。

我怎么能实现这个目标?

1 个答案:

答案 0 :(得分:1)

当您关闭第二个表单时,会自动引发其FormClosed事件。在引发事件之前,您可以向事件注册事件处理程序。这使您可以在事件发生时编写自动执行的代码。

通过向事件添加委托实例来实现在.NET中注册事件处理程序。委托是描述方法签名的类型。如果使用gcnew实例化委托,则将其与代码中的函数关联。您可以自己调用委托(这里不需要),也可以将其传递给其他代码,然后可以调用它。后者用于事件。

对于您的情况,这意味着:

  1. 查看FormClosed事件的委托类型。 FormClosedEventHandler定义为delegate void FormClosedEventHandler(Object^ sender, FormClosedEventArgs^ e)
  2. 这意味着您必须实现一个不返回任何内容(void)并接受两个参数的方法:System :: Object和System :: Windows :: Forms :: FormClosedEventArgs
  3. 实例化FormClosedEventHandler委托并将其与您的方法
  4. 相关联
  5. 在第二个表单上注册FormClosed事件,并启用事件处理程序中的按钮。
  6. 一个例子:

    ref class MainForm
    {
        ...
    
        // event handler function (compatible to the FormClosedEventHandler delegate)
        void OnSecondFormClosed(Object^ sender, FormClosedEventArgs^ e)
        {
            myButton->Enabled = true;
        }
    
        void DoSomethingWithSecondForm(Form^ secondForm)
        {
            // get a disabled Button
            myButton->Enabled = false;
            // create an event handler by instantiating a delegate
            FormClosedEventHandler^ handler = gcnew FormClosedEventHandler(this, &MainForm::OnSecondFormClosed);
            // register event handler
            secondForm->FormClosed += handler;
        }
    
        ...
    }
    

    (我没有编译代码,但这是一般的工作方式)

    当两个涉及的表单都是在同一个线程中创建的时候,不需要再做一些Invoke。否则,您必须将对控件的更改放入创建控件的同一线程中。您可以通过将委托传递给Control::InvokeControl::BeginInvoke来实现此目的。

    // event handler function (compatible to the FormClosedEventHandler delegate)
    void OnSecondFormClosed(Object^ sender, FormClosedEventArgs^ e)
    {
        if (myButton->InvokeRequired)
        {
            // create a delegate to call the same event handler again
            FormClosedEventHandler^ handler = gcnew FormClosedEventHandler(this, &MainForm::OnSecondFormClosed);
            // BeginInvoke causes the delegate to be called asynchronously from the UI thread
            myButton->BeginInvoke(handler, sender, e);
            // nothing to be done here, the actual work happens when the delegate is actually called
            return;
        }
    
        myButton->Enabled = true;
    }