单一表单在启动时隐藏


75

我有一个带有一个窗体的应用程序,在Load方法上,我需要隐藏窗体。

表单将在需要时显示(按照Outlook 2003样式弹出窗口的思路显示),但是我无法弄清楚如何在加载时隐藏表单而不会造成混乱。

有什么建议?

Answers:


110

我来自C#,但在vb.net中应该非常相似。

在主程序文件的Main方法中,您将看到以下内容:

Application.Run(new MainForm());

这将创建一个新的主表单,并将应用程序的生命周期限制为该主表单的生命周期。

但是,如果删除Application.Run()的参数,则该应用程序将在启动时不显示任何表单,并且可以随意显示和隐藏表单。

与其在Load方法中隐藏表单,不如在调用Application.Run()之前初始化表单。我假设表单上会显示一个NotifyIcon,以在任务栏中显示一个图标-即使表单本身尚不可见,也可以显示该图标。从NotifyIcon事件的处理程序进行调用Form.Show()Form.Hide()从中进行处理将分别显示和隐藏表单。


13
到目前为止,我所见过的最好的(也是最简单的)解决方案之一。所有关于将不透明度设置为零,具有单独的Timer实例以隐藏表单等的垃圾,都有几天的代码气味。
nathanchere 2010年

13
据我所知,设计师没有Visible属性。
Dan W

5
Visual Studio 2015和.NET 4.5在这里...设计器没有visible表单的属性。我在俯视什么吗?
本·菲利普

1
如果我错了,请纠正我,Application.Run为Windows窗体提供了带有消息循环的过程。没有它,您窗体内的代码将崩溃。
manit

1
请注意,在这种情况下,Form_Load只有在第一次显示该表单时才会被调用。而且可能永远不会。同时关闭主窗体也不会关闭应用程序。您必须使用Application.Exit
响尾蛇

104

通常,只有在以后使用任务栏图标或其他方法显示表单时,您才这样做,但是即使您从不显示主表单,它也可以很好地工作。

在Form类中创建一个默认为false的布尔值:

private bool allowshowdisplay = false;

然后重写SetVisibleCore方法

protected override void SetVisibleCore(bool value)
{            
    base.SetVisibleCore(allowshowdisplay ? value : allowshowdisplay);
}

因为Application.Run()会在加载表单后设置表单.Visible = true,所以它将拦截该表单并将其设置为false。在上述情况下,它将始终设置为false,直到通过将allowshowdisplay设置为true启用它为止。

现在,将使表单无法在启动时显示,现在,您需要通过设置allowhowdisplay = true来重新启用SetVisibleCore以使其正常运行。您将需要在显示表单的任何用户界面功能上执行此操作。在我的示例中,这是我notiyicon对象中的左击事件:

private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        this.allowshowdisplay = true;
        this.Visible = !this.Visible;                
    }
}

2
谢谢!与这里几乎所有其他建议不同,该建议没有在主窗口中显示简短的闪烁。
安迪

2
这是执行此操作的实际正确方法,因此应该是公认的答案。早在MFC时代,我们曾经做过类似的事情,即处理第一条WM_WINDOWPOSCHANGING消息并在其中隐藏表单以防止“窗口闪烁”。
enriquein 2011年

谢谢,我尝试了接受的答案,但由于我需要显示任务栏图标而无法正常工作,但是效果很好。
奥马尔·库赫吉

这行得通,但是我认为@Jeff的答案更好,因为它不需要使用某些逻辑黑客进行覆盖。
Mark Lakata

1
不幸的是,当我将SetVisibleCore()方法添加到表单时,通知图标根本没有出现,因此之后我无法通过鼠标单击显示它。
Dan W

35

我用这个:

private void MainForm_Load(object sender, EventArgs e)
{
    if (Settings.Instance.HideAtStartup)
    {
        BeginInvoke(new MethodInvoker(delegate
        {
            Hide();
        }));
    }
}

显然,您必须更改您的if条件。


2
这将导致程序闪烁,然后在启动时快速隐藏。
Dan W

我想如果我看不到您的代码,我应该做很多事情。谢谢
M在

为了解决在应用程序启动闪光灯,在设计师设置窗体透明度为0,然后在回调中,调用隐藏(),然后设置不透明度回到100
迈克尔·布雷

20
    protected override void OnLoad(EventArgs e)
    {
        Visible = false; // Hide form window.
        ShowInTaskbar = false; // Remove from taskbar.
        Opacity = 0;

        base.OnLoad(e);
    }

1
我希望隐藏我的表单,但仍在加载并运行它。在这种情况下,此解决方案非常有效。支持您!
Joe Gayetty

我认为这是最好的解决方案,THX :)
Soheyl

15

在表单构建时(根据您的目标,设计器,程序Main或Form构造函数),

 this.WindowState = FormWindowState.Minimized;
 this.ShowInTaskbar = false;

当您需要显示表单时(大概是在NotifyIcon发生事件时),必要时可以反向显示,

 if (!this.ShowInTaskbar)
    this.ShowInTaskbar = true;

 if (this.WindowState == FormWindowState.Minimized)
    this.WindowState = FormWindowState.Normal;

连续的显示/隐藏事件可以更简单地使用Form的Visible属性或Show / Hide方法。


这也适用于Load事件。我认为这就是预期的方式。
Mark Lakata

5

尝试也从任务栏隐藏该应用程序。

为此,请使用此代码。

  protected override void OnLoad(EventArgs e)
  {
   Visible = false; // Hide form window.
   ShowInTaskbar = false; // Remove from taskbar.
   Opacity = 0;

   base.OnLoad(e);
   }

谢谢。鲁胡尔


4

扩展您的主要形式:

using System.Windows.Forms;

namespace HideWindows
{
    public class HideForm : Form
    {
        public HideForm()
        {
            Opacity = 0;
            ShowInTaskbar = false;
        }

        public new void Show()
        {
            Opacity = 100;
            ShowInTaskbar = true;

            Show(this);
        }
    }
}

例如:

namespace HideWindows
{
    public partial class Form1 : HideForm
    {
        public Form1()
        {
            InitializeComponent();
        }
    }
}

本文中的更多信息(西班牙语):

http://codelogik.net/2008/12/30/primer-form-oculto/


3

我为此问题付出了很多努力,但解决方案比我简单得多。我首先尝试了这里的所有建议,但随后对结果不满意,并对其进行了更多调查。我发现如果添加:

 this.visible=false;
 /* to the InitializeComponent() code just before the */
 this.Load += new System.EventHandler(this.DebugOnOff_Load);

运行正常。但是我想要一个更简单的解决方案,事实证明,如果添加以下内容:

this.visible=false;
/* to the start of the load event, you get a
simple perfect working solution :) */ 
private void
DebugOnOff_Load(object sender, EventArgs e)
{
this.Visible = false;
}

3

您将要设置窗口状态为最小化,并在任务栏中显示为false。然后在表单的末尾,将加载集窗口状态最大化并在任务栏中显示为true

    public frmMain()
    {
        Program.MainForm = this;
        InitializeComponent();

        this.WindowState = FormWindowState.Minimized;
        this.ShowInTaskbar = false;
    }

private void frmMain_Load(object sender, EventArgs e)
    {
        //Do heavy things here

        //At the end do this
        this.WindowState = FormWindowState.Maximized;
        this.ShowInTaskbar = true;
    }

3

将其放在您的Program.cs中:

FormName FormName = new FormName ();

FormName.ShowInTaskbar = false;
FormName.Opacity = 0;
FormName.Show();
FormName.Hide();

要显示表单时,请使用以下命令:

var principalForm = Application.OpenForms.OfType<FormName>().Single();
principalForm.ShowInTaskbar = true;
principalForm.Opacity = 100;
principalForm.Show();

1

重写OnVisibleChanged形式

protected override void OnVisibleChanged(EventArgs e)
{
    this.Visible = false;

    base.OnVisibleChanged(e);
}

如果需要显示触发器,可以添加触发器

public partial class MainForm : Form
{
public bool hideForm = true;
...
public MainForm (bool hideForm)
    {
        this.hideForm = hideForm;
        InitializeComponent();
    }
...
protected override void OnVisibleChanged(EventArgs e)
    {
        if (this.hideForm)
            this.Visible = false;

        base.OnVisibleChanged(e);
    }
...
}

0

启动不带表单的应用程序意味着您将不得不自行管理应用程序的启动/关闭。

从不可见的形式开始窗体是一个更好的选择。



0

作为对Groky响应(在我看来,这实际上是迄今为止最好的响应)的补充,我们还可以提及ApplicationContext类,该类还允许(如本文示例中所示)打开两个(或更多)表单在应用程序启动时使用它们,并控制应用程序的生命周期。


0
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    MainUIForm mainUiForm = new MainUIForm();
    mainUiForm.Visible = false;
    Application.Run();
}

0

这对我来说非常合适:

[STAThread]
    static void Main()
    {
        try
        {
            frmBase frm = new frmBase();               
            Application.Run();
        }

当我启动该项目时,所有内容都被隐藏了,包括在任务栏中,除非我需要显示它。


0

我遇到了一个与发布者类似的问题,即在表单完成加载之前触发了在form_Load事件中隐藏表单的代码,从而使Hide()方法失败(不崩溃,只是没有按预期工作)。

其他答案也很有效,但我发现一般来说,form_Load事件通常会遇到此类问题,您想要放入其中的内容可以轻松地放入构造函数或form_Shown事件中。

无论如何,当我移动相同的代码以检查某些事情然后在不需要表单时隐藏该表单(单点登录失败时的登录表单),该表单将按预期工作。


0
    static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Form1 form1 = new Form1();
            form1.Visible = false;
            Application.Run();

        }
 private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
            Application.Exit();
        }

-1

这是一个简单的方法:
在C#中(目前我没有VB编译器)

public Form1()
{
    InitializeComponent();
    Hide(); // Also Visible = false can be used
}

private void Form1_Load(object sender, EventArgs e)
{
    Thread.Sleep(10000);
    Show(); // Or visible = true;
}

如果您不将Show Line添加到Form1_Load中,则即使您将visible设置为false也仍会显示该窗体... -1
EugenioMiró09年

1
-1这不起作用。无论如何,Application.Run()都不利于您显示表单。
Mark Lakata

-2

在设计器中,将表单的Visible属性设置为false。然后避免调用Show()直到需要它为止。

更好的范例是在需要之前不创建表单的实例。


-2

根据各种建议,我要做的就是:

隐藏表格:

Me.Opacity = 0
Me.ShowInTaskbar = false

显示表格:

Me.Opacity = 100
Me.ShowInTaskbar = true

如果用户不小心按下Enter键或在透明区域中键入该怎么办?我认为您也应该这样做Me.Enable = false;
Angshuman Agarwal 2012年

-3

为什么会这样呢?

为什么不只是像控制台应用程序一样开始,并在必要时显示表单?除了将控制台应用程序与表单应用程序分开的参考之外,没有什么其他的。

当您甚至不需要它时,无需贪婪地获取表单所需的内存。


-3

我这样做-从我的角度来看,最简单的方法是:

将表单的“ StartPosition”设置为“手动”,并将其添加到表单的设计器中:

Private Sub InitializeComponent()
.
.
.
Me.Location=New Point(-2000,-2000)
.
.
.
End Sub

确保将位置设置为超出或小于屏幕尺寸的位置。以后,当您要显示表单时,请将“位置”设置为屏幕尺寸内的某个值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.