Как создать приложение.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 и обрабатывать правильно:)

  1. Создайте новое приложение Windows с помощью мастера.
  2. удалять Form1 из кода.
  3. Удалите код в Program.cs при запуске Form1,
  4. Использовать NotifyIcon класс, чтобы создать значок в системном трее (назначить значок для него).
  5. Добавьте к нему контекстное меню.
  6. Или реагировать на NotifyIconщелкайте мышью и различайте правый и левый щелчки, устанавливая контекстное меню и показывая, для какой кнопки (правая / левая) была нажата.
  7. 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

  1. Создайте приложение Windows Forms, установите "Сделать приложение единственного экземпляра" в свойствах
  2. Добавить ContextMenuStrip
  3. Добавьте некоторые записи в полосу контекстного меню, дважды щелкните по ним, чтобы получить обработчики, например, "выход" (двойной щелчок) -> обработчик -> me.Close()
  4. Добавьте NotifyIcon, в конструкторе установите contextMenuStrip к тому, который вы только что создали, выберите значок (вы можете найти его в папке VisualStudio в разделе "common7...")
  5. Установите свойства формы в конструкторе: FormBorderStyle: нет, ShowIcon:false, ShowInTaskbar:false, Непрозрачность:0%, WindowState: свернуто
  6. Добавьте Me.Visible=false в конце Form1_Load, это будет скрывать значок при использовании Ctrl + Tab
  7. Запустите и отрегулируйте по мере необходимости.

Это очень дружественный фреймворк для приложения области уведомлений... достаточно добавить 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;

к вашей форме объекта. Вы увидите только значок на панели задач.

Другие вопросы по тегам