从mainForm显示showDialog的表单不会阻止它,但关闭mainForm会关闭它

时间:2010-04-13 20:20:12

标签: c# winforms multithreading

如何显示需要同步运行的表单。我尝试从线程池的队列工程运行application.run-但有时我有一些无效的句柄。尝试使用常规线程但是当主窗体关闭时它不会关闭它 - 我真的不喜欢杀死线程on_formclosing的想法。如果我使用form.show除了这个事实,主表单中的任何showdialog也会阻止它。处理这个问题的最佳方法是什么?

4 个答案:

答案 0 :(得分:3)

这是你真的不应该解决的问题。在显示对话框时保持启用表单是有风险的。用户可以从该窗体中启动代码,该代码在对话框处于活动状态时不应运行。就像显示另一个对话框一样。

但你可以用诀窍并仔细地做。 ShowDialog()调用迭代所有打开的窗体并禁用它们。您可以通过P /调用EnableWindow()API函数重新启用一个。诀窍是在显示对话框时这样做,Control.BeginInvoke()可以这样做。

最好用一个例子来解释。它需要三个表单和一个主窗体上的按钮,所有这些都有默认名称。在显示对话框时,Form2保持非模态。您可能需要移动它,以便它不会隐藏在表单下面。

  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
      button1.Click += new EventHandler(button1_Click);
    }
    private Form2 mNonModal;
    void button1_Click(object sender, EventArgs e) {
      this.BeginInvoke(new MethodInvoker(makeNonModal));
      new Form3().ShowDialog(this);
    }
    void makeNonModal() {
      if (mNonModal != null) EnableWindow(mNonModal.Handle, true);
    }
    protected override void OnLoad(EventArgs e) {
      mNonModal = new Form2();
      mNonModal.FormClosed += (s, ea) => mNonModal = null;
      mNonModal.Show();
    }
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern void EnableWindow(IntPtr hWnd, bool enable);
  }

答案 1 :(得分:1)

使对话非模态化最简单,即使用Show()而不是ShowDialog()。使对话框成为主窗体的成员,并检查主窗体的关闭事件是否对话框是打开的,如有必要,请将其关闭。

答案 2 :(得分:1)

您可以将线程的IsBackground属性设置为true,然后在所有前台线程关闭时后台线程将关闭。您可以在msdn上阅读有关背景和前台线程的信息。

答案 3 :(得分:0)

尝试使用Show()代替ShowDialog()。另外,创建表单类的对象,例如MyForm^ theForm = gcnew MyForm();