我对C#很陌生,对某些事情有点小问题。我认为线程可能就是答案,但这只是我在寻找解决方案时所采用的Buzz-Word。
namespace Test { public partial class Form1 : Form { private Form2 form2; public Form1() { InitializeComponent(); form2 = new Form2(); } private void runCheck(object source, System.Timers.ElapsedEventArgs e) { form2.ShowDialog(); form2.TopMost = true; } private void runCheckFalse() { form2.Hide(); } }
这只是我的剥离应用程序的快速代码片段,但是在尝试这个时我得到一个错误:跨线程操作无效:控制'Form2'从一个线程访问,而不是创建它的线程。< / p>
另外作为旁注,我使用的是form2.TopMost = true;尝试在其他所有内容上打开窗口,但这通常最终落在Visual Studio等后面
答案 0 :(得分:3)
您需要使用Invoke
才能使用其他主题中的表单。
这是一篇很好的文章,解释了如何使用多个线程的Windows窗体控件:How to: Make Thread-Safe Calls to Windows Forms Controls
试试这个:
namespace Test
{
public partial class Form1 : Form
{
private Form2 form2;
public Form1()
{
InitializeComponent();
form2 = new Form2();
}
private void runCheck(object source, System.Timers.ElapsedEventArgs e)
{
if (form2.InvokeRequired)
{
form2.Invoke(new EventHandler(delegate { form2.ShowDialog(); form2.TopMost = true; }));
}
else
{
form2.ShowDialog();
form2.TopMost = true;
}
}
private void runCheckFalse()
{
if(form2.InvokeRequired)
{
form2.Invoke(new EventHandler(delegate { form2.Hide(); }));
}
else
{
form2.Hide();
}
}
}
}
答案 1 :(得分:1)
您可以通过以下方式修改runCheckFalse方法 - 这是Windows窗体的一个相当标准的模式:
private void runCheckFalse()
{
if(InvokeRequired)
{
BeginInvoke(new MethodInvoker(runCheckFalse));
return;
}
form2.Hide();
}
实际上,这样做是检查我们是否在GUI线程上运行(“如果InvokeRequired”)。如果我们不是,我们在GUI线程上调用自己并立即返回。如果我们在GUI线程上运行,那么我们不需要做任何事情,只需继续正常的方法。
如果您需要使用参数:
private void runCheckFalse(bool someParameter)
{
if(InvokeRequired)
{
BeginInvoke(new MethodInvoker(() => { runCheckFalse(someParameter);}));
return;
}
form2.Hide();
}
答案 2 :(得分:0)
WinForm控件只能从UI线程更新。 Take a look at this blog post,它提供了许多方法来确保更新发生在UI线程上。这是一个很长的帖子,但值得一读。如果您没有时间阅读它,那么快速而肮脏的方法是第一个。
埃里克