C#/.NET - WinForms - 实例化一个窗体但不显示它

24

我在加载事件期间将表单的可见性更改为false,但表单仍然显示。将此.Visible = false; 关联到正确的事件是什么?我想实例化Form1而不显示它。

using System;
using System.Windows.Forms;

namespace TestClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Visible = false;
        }

    }
}

4
我很困惑,这个帖子中有多少人在没有检查结果的情况下就给出了答案。Hide (); Visible = false; 这些都不适用于这种情况。它不像其他表单,它是主要表单,无论你做什么它都会显示出来。这里的人需要在给出虚假答案之前先思考一下。顺便说一句,在 Visual Studio 2010 中,主窗体没有 Visible 属性,根本就不存在。 - user615283
@Draek,说得好。但是你可以使用名为ShowInTaskbar和WindowState的属性组合来实现类似的功能。我已将其添加为答案。 - Jose Cherian
17个回答

24

无论你在表单显示前如何设置Visible属性,它都会弹出。据我所知,这是因为它是当前ApplicationContext的MainForm。一个让表单自动加载但不在应用启动时显示的方法是修改Main方法。默认情况下,它看起来像这样(.NET 2.0 VS2005):

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}
如果您这样做,应用程序会启动,加载您的表单并运行,但是表单不会显示:
[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Form1 f = new Form1();
    Application.Run();        

}

我不太确定这有什么用,但我希望你知道 ; o)

更新:看起来你不需要将Visible属性设置为false,也不需要提供一个ApplicationContext实例(它会在“幕后”自动创建)。相应地缩短了代码。


1
这种解决方案的问题在于关闭窗体并不会关闭应用程序。因此,您必须在FormClose时调用Application.Exit()来进行补偿。当然,除非您的应用程序使用多个窗体,在这种情况下,您需要更加智能一些。幸运的是,我的应用程序只使用一个窗体和系统托盘图标,所以上面的示例完全可以正常工作。 - Chris Kemp
我找到了一种更好的解决这个问题的方法,我作为另一个答案添加了进去。 - Jose Cherian
我不知道为什么这个答案被标记为答案,因为在我的电脑上这个例子不起作用。表单仍然可见... - Anatolii Humennyi
1
@AnatoliiGumennyi,你能提供一下你是怎么做的吗?我刚刚重试了一下(在VS2013中),但是窗体对我来说没有显示出来。 - Fredrik Mörk
谢谢。在尝试了许多其他不同的示例之后,这个最终为我工作了。 - drzounds
显示剩余2条评论

12

我知道这是一个老问题,但我刚刚偶然发现它,很惊讶没有人提到 SetVisibleCore

bool isVisibleCore = false;
protected override void SetVisibleCore(bool value)
{
    base.SetVisibleCore(isVisibleCore);
}
在这段代码片段中,只要 isVisibleCore 保持为 false,表单就会保持不可见状态。如果在实例化表单时将其设置为 false,则不会出现您在 Shown 事件中设置 Visible = false 时会出现的短暂可见性闪烁。

这并没有创建表单。 - Shimon Doodkin
当我在应用程序运行之外创建窗体并没有执行form.show()(可能会在第一次显示时创建组件事件)。因此窗体上的组件未能完全创建。当我尝试与它们交互时,出现了组件未初始化的错误。当我覆盖setvisible或将窗体设置为不可见时,同样会出现错误。 - Shimon Doodkin
解决方法是创建窗体并将其以最小化的窗口状态显示,然后隐藏它并将窗口状态设置为正常。这样做后,onload事件就会被触发。在托盘图标单击后,必须设置左上角高度和宽度,如果其中任何一个不正确,比如-32000,则需要进行调整。 - Shimon Doodkin
1
警告:这不仅会阻止“Shown”事件(您可能期望的),还会阻止“Load”和其他事件。请注意。它们在第一次调用base.SetVisibleCore(true)时被触发。 - Stéphane Gourichon
1
注意:这种方法会阻止关闭窗体(和其他正常的生命周期事件)。请参见http://stackoverflow.com/a/4556649/67392以获取更好的解决方案。 - Richard
显示剩余3条评论

10

我花了一些时间才找到一个有效的解决方案。

在属性窗口下将名为WindowState和ShowInTaskbar的属性设置为Minimized和False。一旦你的窗体完全加载,调用下面的代码行。

        this.ShowInTaskbar = true;
        this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
        //this.WindowState = System.Windows.Forms.FormWindowState.Normal;

注:此解决方案已经在Visual C# 2008 Express Edition上进行测试。


3

设计时将Opacity属性设置为0,当您想显示表单时将其设置回100,如何?


1
采用这种方法,如果用户使用alt + tab键,表单仍然可以访问。 - Richard Ev

2
为了实现无闪烁的显示效果,还需在加载期间将表单位置设定在屏幕外:
private Point startuplocation;

private void Form1_Load(object sender, EventArgs e)
{
    this.startuplocation = this.Location;
    this.Location = new Point(-1000, -1000);
}

private void Form1_Shown(object sender, EventArgs e) //fires first time shown
{
    this.Visible = false;
    this.Location = this.startuplocation;
}

2

我能接受的解决方案是: 表单已创建,并在创建时调用了 on_load 函数。 将 WindowState 设置为最小化,然后在加载时将 visible 设置为 false 和 windowstate 设置为 normal。

private void Form1_Load(object sender, EventArgs e)
{
        this.Visible = false;
        this.WindowState = FormWindowState.Normal;
}

未成功的尝试:

覆盖SetVisibleCore方法的解决方案未能创建表单。

同样地,

Application {
 Form1 f = new Form1();
 Application.Run(); 

):


1

所显示的事件可能会给你想要的结果。尽管表单在隐藏之前会“闪烁”一秒钟。

private void Form1_Shown(object sender, EventArgs e)
    {
        this.Visible = false;
    }

1
只需创建 Form1 的一个实例,不要调用显示它的方法。但我敢打赌你做错了什么。

1
尝试在VisibleChanged事件上进行操作。

1
我建议的是在一个先于_Show事件的事件中实例化表单,例如构造函数,在IntializeComponent()调用之后。

我认为你可能是想隐藏而不是实例化,对吗?无论如何(没有双关语),你必须确保你调用的位置在使窗体可见的调用之后,但在它实际上变得可见之前。 - Adam Robinson
实际上,我建议在显示表单之前初始化所有必要的内容。 - Nikos Steiakakis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接