如何在C#中强制创建Winform句柄?

4
我收到了以下的运行时错误信息:
Invoke或BeginInvoke在控件的窗口句柄创建之前不能被调用。
我认为发生了以下情况。我的winform构造函数正在创建一些对象,其中一个对象接收异步TCP/IP数据。长话短说,我有事件代理,允许接收网络数据的类从Winform调用一个例程将数据打印到文本框中。这样我就可以看到接收到了什么数据。我可以看到数据立即被接收。这发生在winform构造函数完成之前。
据我所知,你不能调用一个winform或winform组件,直到它的句柄被创建。我怀疑这是我违反的规则。据说有一个函数可以强制执行此操作。我尝试在我的winform构造函数中添加以下代码来强制在创建接收TCP/IP数据的类之前创建winform,但是错误仍然存在。
InitializeComponent();
this.CreateControl();
this.HistoryBox.CreateControl();

以下是我的winform委托代码,希望对您有所帮助:

    public void Print_Console_Message(string message)
    {
        Console_Output.Enqueue(message);
        this.Invoke(new EventHandler(PrintToConsole));
    }
    private void PrintToConsole(object sender, EventArgs e)
    {
        string message = Console_Output.Dequeue();

        if (message.Length != 0)
        {
            HistoryBox.AppendText(message + "\n" + "\n");
        }
    }

我意识到有一种方法可以检查对象句柄是否已创建并在这种情况下避免调用,但是,我不仅仅想抑制部分输出。

有人知道我如何强制创建句柄或控件,以便在构造函数完成之前调用委托函数吗?


你能否将需要调用的对象的创建移动到 Load 事件而不是构造函数中?Load 事件在句柄被创建后触发,非常适合这种情况。 - Scott Chamberlain
1个回答

14
根据文档,您可以通过获取.Handle属性来实现此操作。

如果句柄还没有被创建,则引用此属性将强制创建句柄。

或者,您可以监听HandleCreated事件,只有在它被触发后再Invoke

好的,那就成功了。这是我的代码示例:if (this.Handle != null && this.HistoryBox.Handle != null && this.Error_Output != null && this.Dev_Output_Window != null) { } - Michael Bauer
2
如果 uiElement.InvokeRequired == true,则 .Handle 属性会抛出 InvalidOperationException 异常。最好使用 uiElement.CreateControl() 方法,它不受代码修改的影响。 - it3xl
2
如果 InvokeRequiredtrue,那么我期望在调用某个方法时抛出同样的异常。CreateControl() 读起来更好一些,但不能保证创建句柄。 - MrBlue

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接