McLovin
McLovin

Reputation: 1601

"Invoke or BeginInvoke cannot be called on a control until the window handle has been created" only occurs the second time form opens

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 was unhandled - Invoke or BeginInvoke cannot be called on a control until the window handle has been created.

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.

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);
    }

Here's my main form:

    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;
    }

Upvotes: 1

Views: 14745

Answers (1)

joe
joe

Reputation: 8654

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();

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.

Upvotes: 3

Related Questions