Работа с треем. Мигание значка в трее на C#

Данный пост продолжает серию статей о работе с треем. Как видно из заголовка, здесь будет рассмотрена простая и лично мне очень нравящаяся фича – мигание значка в трее. Получится что-то похожее на мигание «заметки» в QIP, сообщающее о наличии непрочитанных сообщений; или на изменение значка, антивируса Касперского, информирующее о его текущем состоянии и прочее.

Вообще, у меня есть несколько идей, как можно интересно использовать эффект мигания или просто циклической смены значков. Не для «промышленных» приложений, конечно, однако знакомые и друзья смогут оценить:) Хотя об этом наверное будет отдельный пост:)

Итак, перейдем к делу. Для создания эффекта мигания нам потребуется помимо NotifyIcon элемент управления Timer. В нем, чтобы запустить отсчет, нужно обязательно установить значение свойства Enabled в true, а свойства Interval сделать больше 0 (в этом примере оно рано 420). Теперь таймер будет генерировать событие Tick каждый 420 миллисекунд. Для того, чтобы заставить значок мигать, остается только в обработчике этого события прописать соответствующий код. (Ну и не забыть подписаться на это событие, естественно.)

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

///
/// флаг для организации мигания
///
private bool _forBlinking = false;
///
/// обрабатываем тик
///
void _timer_Tick(object sender, EventArgs e)
{
    //по флагу определяем, какой значок следует сейчас поставить
    if (_forBlinking)
    {
        _notifyIcon.Icon = _myEmptyIcon;
        _forBlinking = false;
    }
    else
    {
        _notifyIcon.Icon = _myIcon;
        _forBlinking = true;
    }
}

///
/// наша иконка
///
private Icon _myIcon = new Icon("favicon.ico");
///
/// "пустая" иконка
///
private Icon _myEmptyIcon = new Icon("emptyicon.ico");

И, конечно, подписка на событие при инициализации:

//подписываемся на событие тика таймера
_timer.Tick += new EventHandler(_timer_Tick);

Теперь значок мигает. Мы на шаг ближе к собственному клону аськи:)

Вот архив с примером.

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

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=

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

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

  1. я не особо знаком с .net но ваш код это просто писец .зачем вообще таймер?я пробовал ваш код…он жрет 40% процессора.вы сами вообще его запускали?

    вот как надо делать правильно.один из вариантов

    private void StartTread()
    {

    Thread trd = new Thread(new ThreadStart(this.Thread1));
    trd.IsBackground = true;
    trd.Start();
    }

    private void Thread1()
    {

    var icon1 = Properties.Resources.icon1;
    var icon2 = Properties.Resources.icon2;

    {
    for (; ; )
    {
    System.Threading.Thread.Sleep(500);
    if (!stop_)
    {
    blink_ = !blink_;
    notifyIcon1.Icon = blink_ ? icon1 : icon2;
    }
    }

    }
    }

  2. Rosskyавтор

    Код перепроверил только что. У меня «отъедание» процессора остается на значениях, близких к нулю (т.е. 0-2 %). Что с моим вариантом, что с предложенным вами. Интересно, как у вас он умудрился сожрать 40%?! В этом коде нет циклов, только пара условий. На сколько я понимаю логику работы таймера, он не должен активно жрать процессорное время во время простоя. Мне кажется, что у вас «пожиранием» занималось что-то другое.

    А по поводу вашего кода — спасибо. Этот вариант мне нравится больше предложенного мой, т.к. с ним мигание будет продолжаться, даже если дать приложению решать продолжительную вычислительную задачу в главном потоке.

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