Работа с треем. Сворачивание формы в трей на C#

Этот пост открывает серию статей, посвященных работе с треем. Описывать все в одном посте я не буду по одной причине: некоторые аспекты теряются за другими. Сначала я действительно написал статью под заголовком «Как реализовать сворачивание в трей на C#», однако по запросу «сворачивание в трей» на нее пришел только один человек. Остальные же искали нечто другое, не указанное в заголовке статьи, однако, естественно, затронутое в ней. И я не уверен, что, посмотрев на заголовок, они тут же не закрыли вкладку. Не все же будут лезть в конец страницы, если не уверены, что там будет ответ. Я и сам не всегда проверяю, где же на странице находится то, что по мнению поисковика я искал. В конечном итоге написание серии относительно коротких постов должно привести к двум приятностям: повышению релевантности страниц и более удобному поиску материала (это уже для меня лично, чтобы не забыть что и где).

Итак. За работу с областью уведомлений (или треем) в С# отвечает класс NotifyIcon. В нем есть несколько полезных свойств, которые позволяют:

  • назначить значок (свойство Icon);
  • указать контекстное меню для значка (свойство ContextMenu);
  • определить тест-подсказку (свойство Text);
  • свойство Visible позволяет скрыть значок в трее.

Перед использованием его естественно следует «кинуть» на форму в визуальном редакторе или объявить в ручную.

Здесь представлен фрагмент кода небольшой программы, демонстрирующий реализацию сворачивания формы в трей:

    using System;
    using System.Drawing;
    using System.Windows.Forms;

    namespace rosskyru
    {
        public partial class FormForTray : Form
        {
            ///
            /// конструктор формы
            ///
            public FormForTray()
            {
                InitializeComponent();
                //задаем всплывающий текст-подсказку (появляется при наведении указателя на иконку в трее)
                _notifyIcon.Text = "Текст-подсказка";
                //устанавливаем значок, отображаемый в трее:
                //либо один из стандартных:
                //_notifyIcon.Icon = SystemIcons.Error;
                //либо свой из файла:
                _notifyIcon.Icon = new Icon("favicon.ico");
                //подписываемся на событие клика мышкой по значку в трее
                _notifyIcon.MouseClick += new MouseEventHandler(_notifyIcon_MouseClick);
                //подписываемся на событие изменения размера формы
                this.Resize += new EventHandler(FormForTray_Resize);
            }

            ///
            /// здесь хранится состояние окна до сворачивания (максимизированное или нормальное)
            ///
            private FormWindowState _OldFormState;

            ///
            /// обрабатываем событие клика мышью по значку в трее
            ///
            void _notifyIcon_MouseClick(object sender, MouseEventArgs e)
            {
                //проверяем, какой кнопкой было произведено нажатие
                if (e.Button == MouseButtons.Left)//если левой кнопкой мыши
                {
                    //проверяем текущее состояние окна
                    if (WindowState == FormWindowState.Normal || WindowState == FormWindowState.Maximized)//если оно развернуто
                    {
                        //сохраняем текущее состояние
                        _OldFormState = WindowState;
                        //сворачиваем окно
                        WindowState = FormWindowState.Minimized;
                        //скрываться в трей оно будет по событию Resize (изменение размера), которое сгенерировалось после минимизации строчкой выше
                    }
                    else//в противном случае
                    {
                        //и показываем на нанели задач
                        Show();
                        //разворачиваем (возвращаем старое состояние "до сворачивания")
                        WindowState = _OldFormState;
                    }
                }
            }

            ///
            /// обрабатываем событие изменения размера
            ///
            void FormForTray_Resize(object sender, EventArgs e)
            {
                if (FormWindowState.Minimized == WindowState)//если окно "свернуто"
                {
                    //то скрываем его
                    Hide();
                }
            }
        }
    }

Надеюсь, что комментарии в коде объясняют все нюансы программы.

Она делает всего две вещи:

  • сворачивается и разворачивается из трея по щелчку левой кнопки мыши на значке в области уведомлений;
  • запоминает свое старое состояние и разворачивается сразу в него (т.е. если она была развернута на весь экран, а потом свернута в трей, то восстановится она снова на весь экран).

И, напоследок, архив с этим проектом.

Полезная статья? Их будет больше, если вы поддержите меня!

https://money.yandex.ru/embed/small.xml?account=410011399843532&quickpay=small&yamoney-payment-type=on&button-text=06&button-size=l&button-color=orange&targets=%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B8%D0%B2%D0%B0%D1%8E+%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82+lexpenz.com&default-sum=50&successURL=

Архив комментариев

7 комментариев из прежней версии блога. Архив закрыт для новых ответов.

  1. Дочернюю(открытую из другой формы) так свернуть нельзя

  2. Павел, идея сворачивания в трей состоит в том, что сворачивается всё приложение, а не так, что одна форма свернулась, а другая нет. Глупость сказали.

  3. Спасибо. Очень полезная информация.

  4. в нескольких статьях — ссылки на файлы битые. сделайте, что нибудь.

    1. lexpenzавтор

      andre, ссылки поправил, теперь должно скачиваться нормально. Проверьте.

      1. Доброго, как сделать чтобы сразу при запуске форма не была видна, я делал как то на одной программе, но разбирая ее у меня не получается спрятать форму в новой программе

  5. Добавочный вопрос, все сделал как надо, но при нажатии на иконку в трее программа автоматически закрывается и все, хотя должна показать контексное меню.