更改窗体的父线程
Change parent thread of a form
我正在尝试找到一种方法将 winform 线程的父线程更改回 GUI 线程。现在我必须从另一个线程创建表单,但无法从引用它的主表单访问。
这里是我所拥有的示例
public partial class MainForm : Form
{
// local instance of the sub form
private ViewForm SubForm { get; set;} = null;
public MainForm()
{
InitializeComponent();
Task.Run(() =>
{
// set the sub form
SubForm = new ViewForm();
}
// call the rest of the initialization of main form
InitializeCustomControls();
}
private void OpenViewWindow_Click(object sender, EventArgs e)
{
// if the window is instanciated
if (SubForm != null)
{
SubForm.Show();
}
}
}
ViewForm
window 不是 Form
对象。这是自定义第三方 window。它有很多与主题混合的控件和模板。对一个新的空构造函数的唯一调用最多可能需要 7 秒,因此为什么我需要在另一个线程上创建它,同时继续加载我的主 window.
现在我可以调用 window 中的任何方法,但 .Show()
除外,它总是由于线程创建限制而失败。我想避免将线程创建为无休止的 运行 线程,该线程将等待并读取一些对象以告诉他何时显示和隐藏 window.
这是 .Show()
错误:
Cross-thread operation not valid: Control 'ViewForm' accessed from a thread other than the thread it was created on.
我确实尝试了以下方法,但它仍然冻结了我的界面:
Task.Run(() =>
{
// set the sub form
this.Invoke(new MethodInvoker(delegate
{
SubForm = new ViewForm();
}));
}
我想要的是像火一样忘记 GUI 对象的实例化。
这是一个使用 BackGroundWorker
的解决方案:
public partial class MainForm : Form
{
// local instance of the sub form
private ViewForm SubForm { get; set;} = null;
public MainForm()
{
InitializeComponent();
backGroundWorker1.RunWorkerAsync();
InitializeCustomControls();
}
private void OpenViewWindow_Click(object sender, EventArgs e)
{
// if the window is instanciated
if (SubForm != null)
{
SubForm.Show();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
SubForm = new ViewForm();
}
}
已测试创建两种形式,MainForm
与示例中的非常相似,SubView
形式在构造函数中带有 Threading.Sleep(10000)
。
我正在尝试找到一种方法将 winform 线程的父线程更改回 GUI 线程。现在我必须从另一个线程创建表单,但无法从引用它的主表单访问。
这里是我所拥有的示例
public partial class MainForm : Form
{
// local instance of the sub form
private ViewForm SubForm { get; set;} = null;
public MainForm()
{
InitializeComponent();
Task.Run(() =>
{
// set the sub form
SubForm = new ViewForm();
}
// call the rest of the initialization of main form
InitializeCustomControls();
}
private void OpenViewWindow_Click(object sender, EventArgs e)
{
// if the window is instanciated
if (SubForm != null)
{
SubForm.Show();
}
}
}
ViewForm
window 不是 Form
对象。这是自定义第三方 window。它有很多与主题混合的控件和模板。对一个新的空构造函数的唯一调用最多可能需要 7 秒,因此为什么我需要在另一个线程上创建它,同时继续加载我的主 window.
现在我可以调用 window 中的任何方法,但 .Show()
除外,它总是由于线程创建限制而失败。我想避免将线程创建为无休止的 运行 线程,该线程将等待并读取一些对象以告诉他何时显示和隐藏 window.
这是 .Show()
错误:
Cross-thread operation not valid: Control 'ViewForm' accessed from a thread other than the thread it was created on.
我确实尝试了以下方法,但它仍然冻结了我的界面:
Task.Run(() =>
{
// set the sub form
this.Invoke(new MethodInvoker(delegate
{
SubForm = new ViewForm();
}));
}
我想要的是像火一样忘记 GUI 对象的实例化。
这是一个使用 BackGroundWorker
的解决方案:
public partial class MainForm : Form
{
// local instance of the sub form
private ViewForm SubForm { get; set;} = null;
public MainForm()
{
InitializeComponent();
backGroundWorker1.RunWorkerAsync();
InitializeCustomControls();
}
private void OpenViewWindow_Click(object sender, EventArgs e)
{
// if the window is instanciated
if (SubForm != null)
{
SubForm.Show();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
SubForm = new ViewForm();
}
}
已测试创建两种形式,MainForm
与示例中的非常相似,SubView
形式在构造函数中带有 Threading.Sleep(10000)
。