关于C#:加载表单而不显示

关于C#:加载表单而不显示

Load a form without showing it

短版:我想触发Form_Load()事件而不使窗体可见。这不起作用,因为Show()忽略了Visible属性的当前值:

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

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

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

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

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


也许在这里应该指出,您可以在不显示表单的情况下创建表单的窗口。我认为可能有合法的情况要这样做。

无论如何,不??管设计好与否,您都可以这样进行:

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

我认为这不会导致Form_Load()被调用,但是此时您将能够调用f.Invoke()(这是我偶然遇到此SO问题时试图做的事情) 。


在我看来,您需要在这里坐下来重新思考您的方法。我无法想象有一个单一的原因,如果您不打算公开它,则您的公共方法必须采用某种形式。只需上一堂新课。


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

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


来自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的看法-无论如何,逻辑不应该是这种形式。


有时候这会很有用,而不是设计不好。有时这可能是从本机迁移到托管的开始。

例如,如果您要将ac应用程序迁移到.NET,则可以将整个应用程序简单地设置为.NET窗体或面板的子窗口,然后通过摆脱c应用程序菜单,状态逐步迁移到.NET。使用平台调用等将工具栏,工具栏和.NE映射到您的应用程序...

您的C应用程序可能需要一段时间才能加载,但是.NET窗体没有..您可能希望隐藏.NEt窗体,直到您的C应用程序初始化为止。

我将在调用show之后将opacity = 0和visible = false设置为false,然后在加载c应用程序时将其设置为


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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();
    }
}

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


如果将方法公开,则可以直接访问它。但是,调用它时可能会有一些意外的副作用。但是将其公开并直接调用将不会绘制屏幕或打开表单。


推荐阅读