0

每当关闭第二个表单时,我想从主表单启用一个按钮。我读过一些关于调用的东西,但不太了解。

我怎么能做到这一点?

4

1 回答 1

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. 在第二个表单上注册FormClosed事件并在事件处理程序中启用按钮。

一个例子:

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::Invokeor来实现此目的Control::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;
}
于 2013-03-18T09:15:06.640 回答