在创建窗口句柄之前,不能在控件上调用Invoke或BeginInvoke“只发生第二次打开的形式 [英] "Invoke or BeginInvoke cannot be called on a control until the window handle has been created" only occurs the second time form opens

查看:2121
本文介绍了在创建窗口句柄之前,不能在控件上调用Invoke或BeginInvoke“只发生第二次打开的形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发的应用程序是现有应用程序的插件,第一次运行插件时,一切都很好用。但是,当我第二次打开插件时,我收到错误:

The application I am developing is a plugin to an existing application and the first time running the plugin everything works great. However when I open the plugin a second time I get the error:

InvalidOperationException未处理 - 调用或BeginInvoke不能在控件上调用,直到窗口句柄已被创建。

我了解竞争条件,从我读过的所有内容中,尝试在 HandleCreated 是真的,但是我不知道为什么这只是在第二次打开插件时才发生。

I understand race conditions and from everything I've read, this error occurs when trying to access a form element before HandleCreated is true, but I cannot figure out why this is happening only the second time I open the plugin.

这是插件代码。调用 SetProgressBar()时发生错误:

Here is the plugin code. The error occurs when calling SetProgressBar():

    private MainForm mainForm;

    public void StartPlugin()
    {
        mainForm  = new MainForm (this);
        mainForm .ShowDialog();
    }

    public bool GetJoinEnabled()
    {
        mainForm.SetProgressBar(3);
    }

这是我的主要形式:

    private Thread m_JoinThread;
    private JoinPlugin m_Join;

    public MainForm(JoinPlugin zig)
    {
        m_Join = zig;
        InitializeComponent();
        m_JoinThread= new Thread(new ThreadStart(GetJoinData));
        m_JoinThread.Start();
    }

    private void GetJoinData()
    {
       //Get enable join data
        bool result = m_Join.GetJoinEnabled();
    }

    public void SetProgressBar(int value)
    {
        SetProgressCallback del = new SetProgressCallback(SetProgressBarControl);
        this.Invoke(del, value);
    }

    private void SetProgressBarControl(int value)
    {
        progressBar.Value = value;
    }


推荐答案

我猜一点但是我之前一直遇到同样的问题。

I'm guessing a little, but i ran into the same issue some time ago.

您正在窗体构造函数中启动一个线程:

You are starting a thread in the forms constructor:

m_JoinThread.Start();

这将直接启动该线程,并调用 Invoke 某处。此时,表单不会完全启动。

将代码移动到加载事件:

This starts the thread immediatedly and call Invoke somewhere. At this time, the form is not initilized completely.
Move the code to the Load event:

public ZigbeeJoinForm_Load()
{
    m_JoinThread= new Thread(new ThreadStart(GetJoinData));
    m_JoinThread.Start();
}

这样可以确保表单被完全初始化并调用调用是安全的。

This ensures that the form is completely initialized and calling Invoke is safe then.

这篇关于在创建窗口句柄之前,不能在控件上调用Invoke或BeginInvoke“只发生第二次打开的形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆