Как создать приложение.NET Windows Forms, которое работает только в системном трее?
Что мне нужно сделать, чтобы приложение Windows Forms работало в системном трее?
Не приложение, которое можно свернуть в трее, а приложение, которое существует только в трее, не более чем значок, подсказка и меню "щелчка правой кнопкой мыши".
14 ответов
Основной ответ использования NotifyIcon - правильный, но, как и многие другие вещи.NET, в его правильном подходе есть масса тонкостей. Учебное пособие, упомянутое Брэдом, дает хорошее представление об основах, но не затрагивает ни одного из них:
- Правильно ли закрывает приложение из системного трея открытые дочерние формы?
- Обеспечивает ли приложение запуск только одного его экземпляра (применимо к большинству, хотя и не ко всем приложениям в трее)?
- Как открыть дочерние окна WPF, а также дочерние окна WinForms, если это необходимо.
- Как поддерживать динамические контекстные меню.
- Стандартный NotifyIcon существует в пространстве WinForms; я могу сделать чистое решение WPF? (Да, ты можешь!)
У меня только что была опубликована статья на Simple-Talk.com, в которой подробно рассматриваются эти моменты и более подробно описывается среда приложения лотка, которую можно сразу использовать, а также полнофункциональный пример приложения для демонстрации всего на практике. См. Создание приложений для лотков в.NET: Практическое руководство, опубликовано в ноябре 2010 г.
В статье проекта кода " Создание приложения для панели задач" приводится очень простое объяснение и пример создания приложения, которое когда-либо существовало только в системной области.
В основном изменить Application.Run(new Form1());
линия в Program.cs
вместо этого запустить класс, который наследует от ApplicationContext
и иметь конструктор для этого класса инициализировать NotifyIcon
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MyCustomApplicationContext());
}
}
public class MyCustomApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
public MyCustomApplicationContext ()
{
// Initialize Tray Icon
trayIcon = new NotifyIcon()
{
Icon = Resources.AppIcon,
ContextMenu = new ContextMenu(new MenuItem[] {
new MenuItem("Exit", Exit)
}),
Visible = true
};
}
void Exit(object sender, EventArgs e)
{
// Hide tray icon, otherwise it will remain shown until user mouses over it
trayIcon.Visible = false;
Application.Exit();
}
}
Я адаптировал принятый ответ к .NET Core, используя рекомендуемые замены для устаревших классов:
- ContextMenu -> ContextMenuStrip
- MenuItem -> ToolStripMenuItem
Программа.cs
namespace TrayOnlyWinFormsDemo
{
internal static class Program
{
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
Application.Run(new MyCustomApplicationContext());
}
}
}
MyCustomApplicationContext.cs
using TrayOnlyWinFormsDemo.Properties; // Needed for Resources.AppIcon
namespace TrayOnlyWinFormsDemo
{
public class MyCustomApplicationContext : ApplicationContext
{
private NotifyIcon trayIcon;
public MyCustomApplicationContext()
{
trayIcon = new NotifyIcon()
{
Icon = Resources.AppIcon,
ContextMenuStrip = new ContextMenuStrip()
{
Items = { new ToolStripMenuItem("Exit", null, Exit) }
},
Visible = true
};
}
void Exit(object? sender, EventArgs e)
{
trayIcon.Visible = false;
Application.Exit();
}
}
}
Как говорит mat1t - вам нужно добавить NotifyIcon в ваше приложение, а затем использовать что-то вроде следующего кода для установки всплывающей подсказки и контекстного меню:
this.notifyIcon.Text = "This is the tooltip";
this.notifyIcon.ContextMenu = new ContextMenu();
this.notifyIcon.ContextMenu.MenuItems.Add(new MenuItem("Option 1", new EventHandler(handler_method)));
Этот код показывает значок только в системном трее:
this.notifyIcon.Visible = true; // Shows the notify icon in the system tray
Если у вас есть форма (по любой причине), вам потребуется следующее:
this.ShowInTaskbar = false; // Removes the application from the taskbar
Hide();
Щелчок правой кнопкой мыши, чтобы получить контекстное меню, обрабатывается автоматически, но если вы хотите выполнить какое-то действие с левой кнопкой мыши, вам нужно добавить обработчик Click:
private void notifyIcon_Click(object sender, EventArgs e)
{
var eventArgs = e as MouseEventArgs;
switch (eventArgs.Button)
{
// Left click to reactivate
case MouseButtons.Left:
// Do your stuff
break;
}
}
Я написал приложение панели задач с.NET 1.1, и мне не нужна форма.
Прежде всего, установите объект запуска проекта как Sub Main
, определенный в модуле.
Затем создайте программно компоненты: NotifyIcon
а также ContextMenu
,
Не забудьте включить MenuItem
"Выйти" или подобное.
Привязать ContextMenu
к NotifyIcon
,
взывать Application.Run()
,
В обработчике события для Quit MenuItem
не забудьте позвонить на набор NotifyIcon.Visible = False
, затем Application.Exit()
, Добавьте то, что вам нужно ContextMenu
и обрабатывать правильно:)
- Создайте новое приложение Windows с помощью мастера.
- удалять
Form1
из кода. - Удалите код в Program.cs при запуске
Form1
, - Использовать
NotifyIcon
класс, чтобы создать значок в системном трее (назначить значок для него). - Добавьте к нему контекстное меню.
- Или реагировать на
NotifyIcon
щелкайте мышью и различайте правый и левый щелчки, устанавливая контекстное меню и показывая, для какой кнопки (правая / левая) была нажата. Application.Run()
чтобы приложение работало сApplication.Exit()
выйти Илиwhile(bRunning){Application.DoEvents;Thread.Sleep(10);}
, Затем установитеbRunning = false
выйти из приложения.
Приложение "Системный трей" - это обычное приложение для создания выигрышных форм, с той лишь разницей, что оно создает значок в области панели задач Windows. Чтобы создать значок sys.tray, используйте компонент NotifyIcon, вы можете найти его в Панели инструментов (Общие элементы управления) и изменить его свойства: Значок, подсказка. Также это позволяет обрабатывать сообщения о щелчках мышью и двойном щелчке.
И еще одна вещь, для достижения внешнего вида или стандартного приложения в трее. добавьте следующие строки в ваше главное событие шоу формы:
private void MainForm_Shown(object sender, EventArgs e)
{
WindowState = FormWindowState.Minimized;
Hide();
}
Насколько я знаю, вы все равно должны писать приложение, используя форму, но не иметь элементов управления в форме и никогда не устанавливать его видимым. Используйте NotifyIcon (образец MSDN, образец которого можно найти здесь), чтобы написать ваше приложение.
Вот как я это сделал с Visual Studio 2010,.NET 4
- Создайте приложение Windows Forms, установите "Сделать приложение единственного экземпляра" в свойствах
- Добавить ContextMenuStrip
- Добавьте некоторые записи в полосу контекстного меню, дважды щелкните по ним, чтобы получить обработчики, например, "выход" (двойной щелчок) -> обработчик -> me.Close()
- Добавьте NotifyIcon, в конструкторе установите contextMenuStrip к тому, который вы только что создали, выберите значок (вы можете найти его в папке VisualStudio в разделе "common7...")
- Установите свойства формы в конструкторе: FormBorderStyle: нет, ShowIcon:false, ShowInTaskbar:false, Непрозрачность:0%, WindowState: свернуто
- Добавьте Me.Visible=false в конце Form1_Load, это будет скрывать значок при использовании Ctrl + Tab
- Запустите и отрегулируйте по мере необходимости.
Это очень дружественный фреймворк для приложения области уведомлений... достаточно добавить NotificationIcon в базовую форму и изменить автоматически сгенерированный код на код ниже:
public partial class Form1 : Form
{
private bool hidden = false;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.ShowInTaskbar = false;
//this.WindowState = FormWindowState.Minimized;
this.Hide();
hidden = true;
}
private void notifyIcon1_Click(object sender, EventArgs e)
{
if (hidden) // this.WindowState == FormWindowState.Minimized)
{
// this.WindowState = FormWindowState.Normal;
this.Show();
hidden = false;
}
else
{
// this.WindowState = FormWindowState.Minimized;
this.Hide();
hidden = true;
}
}
}
В .Net 6 мне приходилось работать с внутренностями моего класса следующим образом:
private NotifyIcon trayIcon;
private ContextMenuStrip contextMenu1;
private ToolStripMenuItem menuItem1;
public MyCustomApplicationContext()
{
contextMenu1 = new System.Windows.Forms.ContextMenuStrip();
menuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.menuItem1.Text = "E&xit";
this.menuItem1.Click += new System.EventHandler(Exit);
this.contextMenu1.Items.AddRange(
new System.Windows.Forms.ToolStripMenuItem[] {this.menuItem1 });
trayIcon = new NotifyIcon(){Icon = Resources.AppIcon, ContextMenuStrip = this.contextMenu1, Visible = true };
}
Вы можете создать форму, изменить ее, а затем передать ее в
Application.Run
в качестве параметра. :
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
var form = new Form1();
form.Hide();
form.Opacity = 0;
form.ShowInTaskbar = false;
Application.Run(form);
}
}
Добавьте свой
NotifyIcon
а также
ContextMenu
(при необходимости) в вашу форму во время разработки как обычное приложение. Убедитесь, что ваш
Notifyicon
является
Visible
и имеет связанный значок. Это также позволит вам работать с формой, которая может вам понадобиться позже по любой причине.
notifyIcon1->ContextMenu = gcnew System::Windows::Forms::ContextMenu();
System::Windows::Forms::MenuItem^ nIItem = gcnew System::Windows::Forms::MenuItem("Open");
nIItem->Click += gcnew System::EventHandler(this, &your_class::Open_NotifyIcon);
notifyIcon1->ContextMenu->MenuItems->Add(nIItem);
Просто добавь
this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false;
к вашей форме объекта. Вы увидите только значок на панели задач.