11

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

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

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

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

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

我想最干净的解决方案是将任务逻辑从任务表单中拉出并放入控制器类中。然后我可以从主表单和任务表单中使用该类,并且仅在我需要它对用户可见时才加载任务表单。但是,如果加载表单而不显示它是一件容易的事情,那将是一个较小的变化。

4

8 回答 8

19

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

无论如何,无论设计是否好,您都可以这样做:

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

我认为这不会导致 Form_Load() 被调用,但此时您将能够调用 f.Invoke() (当我偶然发现这个 SO 问题时,我正在尝试这样做)。

于 2010-12-10T17:18:24.687 回答
8

在我看来,您需要坐下来重新考虑您的方法。如果您不打算展示它,我无法想象您的公共方法需要采用某种形式的单一原因。只做一个新的类。

于 2008-09-15T21:03:10.197 回答
6

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

重做它可能看起来很痛苦,但是您将改进应用程序的结构并使其更易于维护等。

于 2008-09-15T21:11:47.553 回答
5

来自 MSDN:

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

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

但是,让我们忘记技术细节。我完全同意 Rich B 和 Shaun Austin 的观点——反正逻辑不应该是那种形式。

于 2008-09-15T22:23:06.773 回答
1

有时这会很有用,而不是糟糕的设计。有时它可能是从本地迁移到托管的开始。

例如,如果您将 c++ 应用程序迁移到 .NET,您可以简单地将整个应用程序设为 .NET 表单或面板的子窗口,然后通过摆脱 c++ 应用程序菜单、状态栏、工具栏并使用平台调用等将 .NET 映射到您的应用程序...

您的 C++ 应用程序可能需要一段时间才能加载,但 .NET 表单不会......您可能希望在其中隐藏 .NEt 表单,直到您的 C++ 应用程序自行初始化。

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

于 2013-09-12T11:47:31.627 回答
0

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

于 2008-09-15T21:06:56.660 回答
0

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

于 2008-09-15T21:09:28.840 回答
0

没有一个答案解决了原始问题,因此,添加以下内容,调用 .Show() 以加载表单而不显示它,然后调用 .ShowForm() 以允许它在之后显示:

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();
    }
}
于 2018-08-22T13:07:30.507 回答