C# 如何启动最小化到托盘的 WinForm 应用程序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1730731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to start WinForm app minimized to tray?
提问by jluce50
I've successfully created an app that minimizes to the tray using a NotifyIcon. When the form is manually closed it is successfully hidden from the desktop, taskbar, and alt-tab. The problem occurs when trying to start with the app minimized. At first the problem was that the app would be minimized but would still appear in the alt-tab dialog. Changing the FormBorderStyle to one of the ToolWindow options (from the "None" option) fixed this, but introduced another problem. When the app first starts the titlebar of the minimized window is visible just above the start menu:
我已经成功创建了一个使用 NotifyIcon 最小化到托盘的应用程序。当表单被手动关闭时,它会成功地从桌面、任务栏和 alt 选项卡中隐藏。尝试以最小化应用程序启动时会出现问题。起初的问题是应用程序会被最小化,但仍会出现在 alt-tab 对话框中。将 FormBorderStyle 更改为 ToolWindow 选项之一(来自“无”选项)解决了这个问题,但引入了另一个问题。当应用程序首次启动时,最小化窗口的标题栏在开始菜单的正上方可见:
Opening the form and the closing it causes it to hide properly. I've tried lots of variations, but here's essentially how it's working right now...
打开窗体并关闭它会使其正确隐藏。我已经尝试了很多变化,但这里基本上是它现在的工作方式......
WindowState is set to Minimized in the Designer. After some initialization in the constructor I have the following lines:
WindowState 在设计器中设置为最小化。在构造函数中进行一些初始化后,我有以下几行:
this.Visible = false;
this.ShowInTaskbar = false;
When the NotifyIcon is double-clicked I have the following:
双击 NotifyIcon 时,我有以下内容:
this.WindowState = FormWindowState.Normal;
this.Visible = true;
this.ShowInTaskbar = true;
Like I said, I've tried lots of minor variations on this (this.Hide(), etc.). Is there a way to have the NotifyIcon be the primary component such that I can completely start and dispose of the form while leaving the NotifyIcon running? There's got to be a way to start the app with the form minimized without any of the weirdness. Please help me find it!
就像我说的,我已经尝试了很多小的变化(this.Hide() 等)。有没有办法让 NotifyIcon 成为主要组件,这样我就可以在让 NotifyIcon 运行的同时完全启动和处理表单?必须有一种方法可以在没有任何奇怪的情况下最小化表单的情况下启动应用程序。请帮我找到它!
采纳答案by Hans Passant
The right way to do this is to prevent the form from getting visible in the first place. That requires overriding SetVisibleCore(). Let's assume a context menu for the NotifyIcon with a Show and Exit command. You can implement it like this:
正确的做法是首先防止表单变得可见。这需要覆盖 SetVisibleCore()。让我们假设一个带有 Show 和 Exit 命令的 NotifyIcon 上下文菜单。你可以像这样实现它:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
notifyIcon1.ContextMenuStrip = contextMenuStrip1;
this.showToolStripMenuItem.Click += showToolStripMenuItem_Click;
this.exitToolStripMenuItem.Click += exitToolStripMenuItem_Click;
}
private bool allowVisible; // ContextMenu's Show command used
private bool allowClose; // ContextMenu's Exit command used
protected override void SetVisibleCore(bool value) {
if (!allowVisible) {
value = false;
if (!this.IsHandleCreated) CreateHandle();
}
base.SetVisibleCore(value);
}
protected override void OnFormClosing(FormClosingEventArgs e) {
if (!allowClose) {
this.Hide();
e.Cancel = true;
}
base.OnFormClosing(e);
}
private void showToolStripMenuItem_Click(object sender, EventArgs e) {
allowVisible = true;
Show();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
allowClose = true;
Application.Exit();
}
}
Note a wrinkle with the Load event, it won't fire until the main form is first shown. So be sure to do initialization in the form's constructor, not the Load event handler.
请注意 Load 事件的一个问题,它在主窗体首次显示之前不会触发。所以一定要在表单的构造函数中进行初始化,而不是在 Load 事件处理程序中。
回答by Yogesh
In the constructor, remove these two lines:
在构造函数中,删除这两行:
this.Visible = false;
this.ShowInTaskbar = false;
and add after InitializeComponent();
:
并在之后添加InitializeComponent();
:
this.WindowState = FormWindowState.Minimized;
In designer, set ShowInTaskbar
to false
& FormWindowState
to Normal
.
在设计中,设置ShowInTaskbar
到false
与FormWindowState
到Normal
。
EDIT:If you post the same in Load event, the window does get minimized but still shows minimized on the desktop. I think this is a bug.
编辑:如果您在 Load 事件中发布相同的内容,窗口确实会最小化,但仍会在桌面上显示为最小化。我认为这是一个错误。
回答by Justin Clarke
When minimizing an application and you want to hide it from Alt+Tab:
当最小化一个应用程序并且你想从 Alt+Tab 中隐藏它时:
You also need to set the Opacity to stop the titlebar showing near the Start Menu when you set the Border Style to a Tool Window.
当您将边框样式设置为工具窗口时,您还需要设置不透明度以停止在开始菜单附近显示标题栏。
On Minimize Event:
关于最小化事件:
this.Visible = false;
this.Opacity = 0;
this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
this.ShowInTaskbar = false;
On Normalize Event:
在标准化事件上:
this.Visible = true;
this.Opacity = 100;
this.FormBorderStyle = FormBorderStyle.FixedSingle; //or whatever it was previously set to
this.ShowInTaskbar = true;
回答by Alex
I'm reading all the answers and see hacks and black magic... (no offense, mates)
我正在阅读所有答案并看到黑客和黑魔法......(没有冒犯,伙计们)
Guys, no hacks needed. You don't even have need to set "ShowInTaskbar=false" and other stuff. Just do this:
伙计们,不需要黑客。您甚至不需要设置“ShowInTaskbar=false”和其他东西。只需这样做:
//"Form Shown" event handler
private void Form_Shown(object sender, EventArgs e)
{
//to minimize window
this.WindowState = FormWindowState.Minimized;
//to hide from taskbar
this.Hide();
}
NOTE:I strongly recommend NOT TOUCHING the "ShowInTaskbar" property. For example, if your application registers system-wide hotkeys or other similar stuff (hooks, etc) - setting ShowInTaskBar=false and minimizing your app will prevent Windows from sending some messages to your window... And your hooks/hotkeys/etc will stop working.
注意:我强烈建议不要触摸“ShowInTaskbar”属性。例如,如果您的应用程序注册了系统范围的热键或其他类似的东西(钩子等) - 设置 ShowInTaskBar=false 并最小化您的应用程序将阻止 Windows 向您的窗口发送一些消息......而您的钩子/热键/等将停止工作。
回答by David R
This "quick and dirty fix" worked for me:
这个“快速而肮脏的修复”对我有用:
$form1.FormBorderStyle = "fixedtoolwindow"
$form1.top = -1000000
$form1.Left = -1000000
$form1.Width = 10
$form1.Height = 10
$form1.WindowState = "normal"
$form1.ShowInTaskbar = $False
$form1.Opacity = 0
$form1.Hide()
Hope it helps someone else...
希望它可以帮助别人...
回答by Xiang Yang Liao
Move the following code from the Form
's constructor to Form_Main_Load()
. With the same setup on Notification_Icon when Form_Resize()
.
将以下代码从Form
的构造函数移至Form_Main_Load()
. 使用相同的设置Notification_Icon when Form_Resize()
。
// Hide the Form to System Tray
this.WindowState = FormWindowState.Minimized;