加载表单而不显示它

时间:2008-09-15 21:00:50

标签: c# winforms

简短版本:我想在不使表单可见的情况下触发Form_Load()事件。这不起作用,因为Show()忽略Visible属性的当前值:

tasksForm.Visible = false;
tasksForm.Show();

长版本:我有一个WinForms应用程序,有两种形式:main和tasks。始终显示主窗体。用户可以单击按钮打开任务表单,也可以单击某些按钮直接运行任务而无需打开任务表单。

当用户要求直接运行任务时,我想在任务表单上调用一些公共方法而不显示它。不幸的是,任务逻辑依赖于Form_Load()事件中发生的事情。我能找到触发Form_Load()的唯一方法是调用Show()。我能做的最好的事情是将表单显示在最小化状态:

tasksForm.WindowState = FormWindowState.Minimized;
tasksForm.Show();

我认为最干净的解决方案是将任务逻辑从任务表单中拉出来并转换为控制器类。然后我可以从主窗体和任务窗体中使用该类,并且只在我需要用户可见时才加载任务窗体。但是,如果在不显示表单的情况下加载表单很容易,那么这将是一个较小的更改。

8 个答案:

答案 0 :(得分:15)

也许应该注意,可以导致在不显示表单的情况下创建表单的窗口。我认为可能存在想要这样做的合法情况。

无论如何,好的设计与否,你可以这样做:

MyForm f = new MyForm();
IntPtr dummy = f.Handle; // forces the form Control to be created

我认为这不会导致调用Form_Load(),但是此时你可以调用f.Invoke()(这是我在偶然发现这个问题时试图做的事情)

答案 1 :(得分:8)

听起来我觉得你需要坐下来重新思考你的方法。如果你不打算展示它,我无法想象你的公共方法需要在一个表单中的一个原因。做一个新课。

答案 2 :(得分:6)

我完全同意Rich B,您需要查看放置应用程序逻辑的位置,而不是尝试使用WinForms机制。您的任务表单公开的所有这些操作和数据应该在一个单独的类中说某种应用程序控制器或您的主表单所持有的东西然后由您的任务表单用于在需要时读取和显示数据但不是需要一个表格来实例化存在。

重做它似乎很痛苦,但你会改进应用程序的结构并使其更易于维护等。

答案 3 :(得分:5)

来自MSDN:

  

<强> Form.Load
  在第一次显示表单之前发生。

意味着唯一会导致表单加载的是显示它 Form.Show();Form.Visible = true;完全相同。基本上,在幕后,Show会检查各种条件,然后将Visible设置为true。很明显,在显示表单之前将visible设置为false(它已经是)是没有意义的。

但是让我们忘记技术细节。我完全赞同Rich B和Shaun Austin - 无论如何逻辑不应该是那种形式。

答案 4 :(得分:1)

有时如果没有糟糕的设计,这将是有用的。有时它可能是从本机迁移到托管的开始。

如果您正在将c ++应用程序迁移到.NET,例如,您可以简单地将您的整个应用程序设置为.NET表单或面板的子窗口,并通过删除您的c ++应用程序菜单逐渐迁移到.NET。状态栏,工具栏和映射teh。使用平台调用等到您的应用程序...

您的C ++应用程序可能需要一段时间才能加载,但.NET表单并不是......您可能希望在您的c ++应用程序初始化之前隐藏.NEt表单。

在调用show之后我将opacity = 0和visible = false设置为false,然后当你的c ++ app加载时,然后反转。

答案 5 :(得分:0)

如果你将方法设为公开,那么你可以直接访问它......但是,当你调用它时可能会有一些意想不到的副作用。但是将其公开并直接调用它不会绘制屏幕或打开表单。

答案 6 :(得分:0)

将表单类的强制初始化代码从Load事件处理程序移动到构造函数中。对于Form类,实例的实例化(通过构造函数),表单加载和表单可见性是三个不同的事情,并且不需要同时发生(尽管它们显然需要按顺序发生)。 / p>

答案 7 :(得分:0)

所有答案都不能解决原始问题,因此,添加以下内容,调用.Show()以加载表单而不显示该表单,然后调用.ShowForm()以使其可见(如果需要):< / p>

private volatile bool _formVisible;
protected override void SetVisibleCore(bool value)
{
    base.SetVisibleCore(_formVisible);
}
public void ShowForm()
{
    _formVisible = true;
    if (InvokeRequired)
    {
        Invoke((Action) Show);
    }
    else
    {
        Show();
    }
}