在创建窗口句柄之前,不能在控件上调用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
问题描述
我正在开发的应用程序是现有应用程序的插件,第一次运行插件时,一切都很好用。但是,当我第二次打开插件时,我收到错误:
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屋!