加载表单而不显示它
简短版:我想触发Form_Load()事件而不使窗体可见。这不起作用,因为Show()忽略了Visible属性的当前值:
tasksForm.Visible = false; tasksForm.Show();
长版:我有一个WinForms应用程序,有两种形式:主程序和任务。主窗体始终显示。用户可以单击一个按钮打开任务表单,或者单击一些直接运行任务而不打开任务表单的按钮。
当用户要求直接运行任务时,我只想在任务表单上调用一些公共方法而不显示它。不幸的是,任务逻辑取决于Form_Load()事件中发生的事情。我可以找到触发Form_Load()的唯一方法是调用Show()。我所能做的最好的就是以最小化状态显示表单:
tasksForm.WindowState = FormWindowState.Minimized; tasksForm.Show();
我认为最干净的解决方案是将任务逻辑从任务表单中拉出并进入控制器类。然后,我可以从主表单和任务表单中使用该类,并且仅在需要用户可见时才加载任务表单。但是,如果在不显示表单的情况下加载表单很容易,那将是一个较小的更改。
解决方案
回答
在我看来,我们需要在这里坐下来重新思考方法。我不能想象有一个单一的原因,如果我们不打算公开它,则公共方法必须采用某种形式。刚上一堂新课。
回答
如果将方法公开,则可以直接访问它。但是将其公开并直接调用将不会绘制屏幕或者打开表单。
回答
将表单类的强制初始化代码从" Load"事件处理程序中移出到构造函数中。对于Form类,实例的实例化(通过构造函数),表单加载和表单可见性是三件不同的事情,不需要同时发生(尽管它们显然确实需要按此顺序发生)。
回答
我完全同意Rich B,我们需要查看放置应用程序逻辑的位置,而不是试图混淆WinForms机制。 Tasks表单公开的所有这些操作和数据实际上应该在一个单独的类中,例如某种应用程序控制器或者主表单所持有的某种东西,然后由任务表单用于在需要时读取和显示数据,但不需要需要实例化存在的形式。
重做它似乎很痛苦,但是我们将改善应用程序的结构并使其更易于维护等。
回答
从MSDN:
Form.Load Occurs before a form is displayed for the first time.
唯一会导致加载表单的是显示表单。
Form.Show();和Form.Visible = true;是完全一样的东西。基本上,Show在后台检查各种条件,然后将Visible设置为true。因此很明显,在显示表单之前将visible设置为false(已经是)是没有意义的。
但是,让我们忘记技术性。我完全同意Rich B和Shaun Austin的观点,无论如何都不应该采用这种逻辑。
回答
也许应该在这里指出,我们可以在不显示表单的情况下创建表单的窗口。我认为可能会有合法的情况要这样做。
无论如何,不管设计好与否,我们都可以这样做:
MyForm f = new MyForm(); IntPtr dummy = f.Handle; // forces the form Control to be created
我不认为这会导致Form_Load()被调用,但是此时我们将能够调用f.Invoke()(这是我偶然遇到此SO问题时试图做的事情)。