我有一个带有一个窗体的应用程序,在Load方法上,我需要隐藏窗体。
该表单将在需要时显示(按照Outlook 2003样式弹出窗口的思路显示),但是我无法弄清楚如何在加载时隐藏表单而不会造成混乱。
有什么建议?
我来自C#,但在vb.net中应该非常相似。
在主程序文件的Main方法中,您将看到以下内容:
1
| Application.Run(new MainForm()); |
这将创建一个新的主表单,并将应用程序的生命周期限制为该主表单的生命周期。
但是,如果删除Application.Run()的参数,则该应用程序将在不显示任何表单的情况下启动,并且可以随意显示和隐藏表单。
与其在Load方法中隐藏表单,不如在调用Application.Run()之前初始化表单。我假设表单上会显示一个NotifyIcon,以在任务栏中显示图标-即使表单本身尚不可见,也可以显示该图标。从NotifyIcon事件的处理程序调用Form.Show()或Form.Hide()将分别显示和隐藏表单。
通常,只有在以后使用托盘图标或其他方法显示表单时,您才这样做,但是即使您从不显示主表单,它也可以很好地工作。
在Form类中创建一个默认为false的布尔值:
1
| private bool allowshowdisplay = false; |
然后重写SetVisibleCore方法
1 2 3 4
| protected override void SetVisibleCore(bool value)
{
base.SetVisibleCore(allowshowdisplay ? value : allowshowdisplay);
} |
因为Application.Run()会在加载表单后设置表单.Visible = true,所以它将拦截该表单并将其设置为false。在上述情况下,它将始终设置为false,直到通过将allowhowdisplay设置为true启用它为止。
现在,将使表单无法在启动时显示,现在,您需要通过设置allowhowdisplay = true来重新启用SetVisibleCore以使其正常运行。您将需要在显示表单的任何用户界面功能上执行此操作。在我的示例中,这是我notiyicon对象中的左击事件:
1 2 3 4 5 6 7 8
| private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
this.allowshowdisplay = true;
this.Visible = !this.Visible;
}
} |
我用这个:
1 2 3 4 5 6 7 8 9 10
| private void MainForm_Load(object sender, EventArgs e)
{
if (Settings.Instance.HideAtStartup)
{
BeginInvoke(new MethodInvoker(delegate
{
Hide();
}));
}
} |
显然,您必须更改if条件。
1 2 3 4 5 6 7 8
| protected override void OnLoad(EventArgs e)
{
Visible = false; // Hide form window.
ShowInTaskbar = false; // Remove from taskbar.
Opacity = 0;
base.OnLoad(e);
} |
在构建表单时(根据您的目标,是设计器,程序Main还是Form构造函数),
1 2
| this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false; |
当您需要显示表单时(大概是在NotifyIcon发生事件时),必要时可以反向显示,
1 2 3 4 5
| if (!this.ShowInTaskbar)
this.ShowInTaskbar = true;
if (this.WindowState == FormWindowState.Minimized)
this.WindowState = FormWindowState.Normal; |
连续的显示/隐藏事件可以更简单地使用Form的Visible属性或Show / Hide方法。
尝试也从任务栏隐藏该应用程序。
为此,请使用此代码。
1 2 3 4 5 6 7 8
| protected override void OnLoad(EventArgs e)
{
Visible = false; // Hide form window.
ShowInTaskbar = false; // Remove from taskbar.
Opacity = 0;
base.OnLoad(e);
} |
谢谢。
鲁胡尔
用这个扩展您的主要形式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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);
}
}
} |
例如:
1 2 3 4 5 6 7 8 9 10
| namespace HideWindows
{
public partial class Form1 : HideForm
{
public Form1()
{
InitializeComponent();
}
}
} |
本文中的更多信息(西班牙语):
http://codelogik.net/2008/12/30/primer-form-oculto/
您将要设置窗口状态为最小化,并在任务栏中显示为false。然后,在表单末尾,将加载集窗口状态最大化并在任务栏中显示为true
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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;
} |
我为此问题付出了很多努力,但解决方案比我要简单得多。
我首先尝试了这里的所有建议,但随后我对结果不满意并进行了更多调查。
我发现如果添加:
1 2 3
| this.visible=false;
/* to the InitializeComponent() code just before the */
this.Load += new System.EventHandler(this.DebugOnOff_Load); |
运行正常。
但是我想要一个更简单的解决方案,事实证明,如果添加以下内容:
1 2 3 4 5 6 7 8
| 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;
} |
将其放在您的Program.cs中:
1 2 3 4 5 6
| FormName FormName = new FormName ();
FormName.ShowInTaskbar = false;
FormName.Opacity = 0;
FormName.Show();
FormName.Hide(); |
要显示表单时,请使用以下命令:
1 2 3 4
| var principalForm = Application.OpenForms.OfType<FormName>().Single();
principalForm.ShowInTaskbar = true;
principalForm.Opacity = 100;
principalForm.Show(); |
重写OnVisibleChanged形式
1 2 3 4 5 6
| protected override void OnVisibleChanged(EventArgs e)
{
this.Visible = false;
base.OnVisibleChanged(e);
} |
如果需要显示触发器,可以添加触发器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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);
}
...
} |
我遇到了一个与发布者类似的问题,即在表单完成加载之前触发了在form_Load事件中隐藏表单的代码,从而使Hide()方法失败(不崩溃,只是没有按预期工作)。
其他答案很有效,但是我发现一般来说,form_Load事件通常会遇到此类问题,您想要放到那里的内容可以轻松地放在构造函数或form_Shown事件中。
无论如何,当我移动相同的代码以检查某些事情然后在不需要表单时隐藏该表单(单点登录失败时的登录表单),该表单将按预期工作。
启动不带表单的应用程序意味着您将不得不自行管理应用程序的启动/关闭。
从不可见的形式开始窗体是一个更好的选择。
此示例支持完全隐身,并且仅在系统托盘中支持NotifyIcon,而无需单击,等等。
此处更多信息:http://code.msdn.microsoft.com/TheNotifyIconExample
作为对Groky响应的补充(在我看来,这实际上是迄今为止最好的响应),我们还可以提及ApplicationContext类,该类还允许(如本文示例中所示)打开两个(或更多)表单在应用程序启动时使用它们,并控制应用程序的生命周期。
1 2 3 4 5 6 7 8
| static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainUIForm mainUiForm = new MainUIForm();
mainUiForm.Visible = false;
Application.Run();
} |
这是一个简单的方法:
在C#中(目前我没有VB编译器)
1 2 3 4 5 6 7 8 9 10 11
| 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;
} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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 2 3 4 5 6 7 8
| [STAThread]
static void Main()
{
try
{
frmBase frm = new frmBase();
Application.Run();
} |
当我启动该项目时,所有内容都被隐藏,包括任务栏中的内容,除非我需要显示它。
在设计器中,将表单的Visible属性设置为false。然后避免调用Show()直到需要它为止。
更好的范例是在需要之前不创建表单的实例。
为什么会这样呢?
为什么不像控制台应用程序那样开始,并在必要时显示表单?除了将控制台应用程序与表单应用程序分开的参考之外,没有什么其他的。
当您甚至不需要它时,无需贪婪地获取表单所需的内存。
我这样做是这样-从我的角度来看,最简单的方法是:
将表单的" StartPosition"设置为"手动",并将其添加到表单的设计器中:
1 2 3 4 5 6 7 8 9
| Private Sub InitializeComponent()
.
.
.
Me.Location=New Point(-2000,-2000)
.
.
.
End Sub |
确保将位置设置为超出或小于屏幕尺寸的位置。以后,当您要显示表单时,请将"位置"设置为屏幕尺寸内的某个值。
根据各种建议,我要做的就是:
隐藏表单:
1 2
| Me.Opacity = 0
Me.ShowInTaskbar = false |
显示表格:
1 2
| Me.Opacity = 100
Me.ShowInTaskbar = true |