在使用其';之前,我如何等待窗体句柄已创建;组件

本文关键字:等待 窗体 组件 创建 句柄 何等待 之前 | 更新日期: 2023-09-27 18:20:37

我正在动态实例化一个Form。在创建句柄之前,我无法与Form上的组件(如TextBox)进行交互(否则,将引发异常)。

目前我使用while循环阻塞线程:

public void OutputDesktopFrame(MessagingService service, DesktopFrame desktopFrame)
{
    IRemoteDesktopView view = GetView(service);
    view.UpdateFrame(desktopFrame);
}
private IRemoteDesktopView GetView(MessagingService service)
{
    T view;
    bool viewExists = _views.TryGetValue(service, out view);
    if (viewExists == false)
    {
        view = CreateAndShowView(service);
    }
    return view;
}
private T CreateAndShowView(MessagingService service)
{
    T remoteDesktopView = new T();
    _views.Add(service, remoteDesktopView);
    Thread pumpThread = new Thread(() => remoteDesktopView.ShowDialog());
    pumpThread.Start();

    while (remoteDesktopView.IsHandleCreated == false)
    {
        //Do not return until the handle has been created!
    }
    return remoteDesktopView;
}

我不喜欢这种机制。我正在寻找一个优雅的解决方案。

请考虑到我正在针对接口进行编码。我曾想过使用ManualResetEvent或类似的东西,但必须在实现接口的每个窗体中实现和处理ManualResetAvent听起来对我没有吸引力。如果你不同意我的观点,那也没关系。我只是怀疑我目前的解决方案不是最优雅的。

在使用其';之前,我如何等待窗体句柄已创建;组件

您可以向HandleCreated事件处理程序添加代码,如下所示:

private void Form1_HandleCreated(object sender, EventArgs e){
   //your code
}

该事件未在"属性"窗口中列出,您必须使用以下代码注册事件处理程序:

HandleCreated += Form1_HandleCreated;

您必须等待以某种方式创建句柄。因此,您将在代码中的某个地方得到类似while (form.IsHandleCreated == false) { ... }的东西。唯一的问题是把它放在哪里。

如果你像上面的例子那样做,那么每次创建表单时都需要对while循环进行编码。如果你选择了前面提到的替代方案,使用表单引发的事件,你需要在每个表单中实现它(并创建一个事件处理程序并将其挂接)。

我不知道CreateAndShowForm()是一种框架方法,还是你可以自己改变的方法。如果你能改变它,那就是我等待的地方。这样,您只需要对其进行一次编码。

避免代码重复的另一种方法是在表单中处理它,在您自己的抽象表单基类中实现它,并从该类派生实际表单。在我看来,这对这个问题来说完全是小题大做——付出太多却收效甚微。

如果您不能更改CreateAndShowForm(),我建议您使用上面的示例-是的,它肯定不优雅,但它可以完成工作,源代码易于理解,并且不需要额外的事件处理工作。