如何制作一个无模式的“块”?

时间:2010-03-07 05:07:20

标签: winforms modal-dialog

我有一个同时显示两个表单/窗口的应用程序。第一个用Form.Show()方法显示,因此它是无模式的并浮动到一侧。第二种形式用Form.ShowDialog()显示,所以它是模态的,它会阻塞。

它阻塞的事实很重要,因为与第一种形式(基本上只是装饰)不同,第二种形式获取重要信息,因此我不希望我的程序在关闭之前继续运行。

不幸的是,我现在需要允许用户与第一个表单进行一些有限的交互(调整它的能力,以及其他轻微的视觉调整),同时还会显示第二个表单。

显然,当第二个对话框是模态时,这不起作用。所以要么我需要找到一种方法来使第二种形式无模式但在打开时仍然阻塞...或者我需要使第一种形式以某种方式可访问而第二种形式是模态可见的。

我是一名经验丰富的Java Swing程序员,但我对.NET表单还不熟悉,所以也许这里有一个明显的答案我只是因为我不熟悉.NET api而错过了? / p>

2 个答案:

答案 0 :(得分:4)

可以通过相反的方式实现,保持启用帮助器形式。然而,这需要一些技巧。 ShowDialog()方法调用迭代应用程序中的顶层窗口并调用它们上的EnableWindow()来禁用它们。您可以通过自己调用EnableWindow来撤消此操作。有一件事是棘手的,你不能,ShowDialog()阻止。 BeginInvoke()可以解决这个问题。这是一个例子:

  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }
    protected override void OnLoad(EventArgs e) {
      mHelper = new Form2();
      mHelper.Show();
      mHelper.FormClosed += (s, ea) => mHelper = null;
    }
    Form2 mHelper;

    private void EnableForm2() {
      if (mHelper.IsHandleCreated) EnableWindow(mHelper.Handle, true);
    }
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool EnableWindow(IntPtr hWnd, bool enable);

    private void button1_Click(object sender, EventArgs e) {
      this.BeginInvoke(new Action(() => EnableForm2()));
      using (var dlg = new Form3()) {
        if (dlg.ShowDialog(this) == DialogResult.OK) {
          // etc...
        }
      }
    }
  }

答案 1 :(得分:1)

我不相信你可以按照你提出的方式做到这一点。在不了解程序或表单的任何其他内容的情况下,我最好的建议是修改表单以便您可以创建一个表单模式,或者提出一些机制来阻止用户继续操作而不完成所有必需的信息目前的模式形式。

我在这里假设我要说的话......如果我错了,我会撤回这个,但我假设你有一个主要形式,而这两种形式你是谈论的是在主要形式中发生某些事件时显示的两种形式。最后,我假设在没有表格A所需信息的情况下,主表格中有一些过程无法正确完成。

假设是这种情况,而表格A目前是模态表格,表格B是非模态表格,我建议做以下事项:

  • 在表单A中,添加一个公共布尔属性以跟踪是否已填写所有必需信息。
  • 更改表单A所以它不是使用ShowDialog()打开所以它不是模态的。 (这将允许与表格B互动)
  • 在表单A的OnClosing事件中,检查是否已填写所需信息,如果没有,则取消该事件。
  • 在主窗体中,在适当的任何点检查表格A上的信息IsAllFilledIn的属性。如果ht为false,则再次显示Form A(或重新聚焦)

同样,我不确定你的要求,但你应该能找到一些技巧来解决这个问题。我提供了以前的主要是为了让你的想法开箱即用。

所有这些都说,更简单的方法是修改表单,以便所有字段都在模态表单上。