C#打开一个表单,然后从另一个方法关闭它

我对C#很陌生,对某些事情有点小问题。 我认为线程可能就是答案,但这只是我在寻找解决方案时所采用的Buzz-Word。

名称空间测试
 {
    公共部分类Form1:表格
     {
        私人Form2 form2;

        公共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’从一个线程访问,而不是创建它的线程。

另外作为旁注,我使用的是form2.TopMost = true; 尝试在其他所有内容上打开窗口,但这通常最终落在Visual Studio等后面

您需要使用Invoke才能使用其他线程中的表单。

这是一篇很好的文章,解释了如何从多个线程使用Windows窗体控件: 如何:对Windows窗体控件进行线程安全调用

试试这个:

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

您可以通过以下方式修改runCheckFalse方法 – 这是Windows窗体的一个相当标准的模式:

 private void runCheckFalse() { if(InvokeRequired) { BeginInvoke(new MethodInvoker(runCheckFalse)); return; } form2.Hide(); } 

实际上,这样做是检查我们是否在GUI线程上运行(“if InvokeRequired”)。 如果我们不是,我们在GUI线程上调用自己并立即返回。 如果我们在GUI线程上运行,那么我们不需要做任何事情,只是像往常一样继续使用该方法。

如果您需要使用参数:

 private void runCheckFalse(bool someParameter) { if(InvokeRequired) { BeginInvoke(new MethodInvoker(() => { runCheckFalse(someParameter);})); return; } form2.Hide(); } 

WinForm控件只能从UI线程更新。 看一下这篇博客文章 ,它提供了许多方法来确保在UI线程上进行更新。 这是一个很长的post,但值得一读。 如果您没有时间阅读它,那么快速而肮脏的方法是第一个。

埃里克