Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
478 / 241 / 74
Регистрация: 25.05.2012
Сообщений: 1,138
Записей в блоге: 1
.NET 6

События и всплывающие уведомления NotifyIcon

17.01.2023, 13:55. Показов 1308. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день!

В фоновом потоке генерятся события на которые подписан основной поток UI.
Если события генерятся с очень коротким интервалом (т.е. по сути одно за другим) то NotifyIcon показывает только последнее уведомление.

Как заставить его показать уведомления о всех событиях?

Подписка и обработчик:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        public FrmMain()
        {
            InitializeComponent();
            
            someBackgroundObject.SomeEvent += SomeBackgroundObject_SomeEvent;
        }
 
        private void SomeBackgroundObject_SomeEvent(object? sender, SomeEventArgs e)
        {
            string message = string.Empty;
            string header = string.Empty;
            
            //...
 
            notifyIconMain.ShowBalloonTip(1000, header, message, ToolTipIcon.Info);
        }
Логика события:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    public class SomeBackgroundObject
    {
        public event EventHandler<SomeEventArgs> SomeEvent;
 
        protected virtual void OnSomeEvent(SomeEventArgs e)
        {
            SomeEvent?.Invoke(this, e);
        }
        public void SomeMethod()
        {
 
            //...do something
            OnSomeEvent(new SomeEventArgs());
 
            //...do some more
            OnSomeEvent(new SomeEventArgs());
        }
 
    }
Метод SomeMethod() вызывается с помощью BackgroundWorker
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.01.2023, 13:55
Ответы с готовыми решениями:

Кнопка в NotifyIcon, windows 10 уведомления
У меня есть вот такой код и я хочу чтобы в NotifyIcon была кнопка с переадресацией на сайт. Как это сделать? using System; using...

Всплывающие окна, уведомления
Добрый день! Подскажите пожалуйста! На данный момент изучаю Asp.Net core шаблон MVC. Что необходимо изучить, чтобы у меня были всплывающие...

Всплывающие уведомления
Всем привет. В общем кто то может сталкивался с Notification. Так вот скажите как же сделать эти уведомления хотя бы примеры. ...

5
2287 / 1603 / 400
Регистрация: 26.06.2017
Сообщений: 4,756
Записей в блоге: 1
17.01.2023, 16:14
Цитата Сообщение от NewOrdered Посмотреть сообщение
Как заставить его показать уведомления о всех событиях?
Заставить не получится (см. комментарий), но можно организовать работу NotifyIcon должным образом. Для этого на уровне формы создайте очередь уведомлений NotifyIcon, там же создайте метод, который будет в цикле показывать очередное уведомление очереди и дожидаться окончания его отображения. Затем в обработчике SomeBackgroundObject_SomeEvent помещайте уведомление из параметра в эту очередь, после чего вызывайте метод отображения. Метод отображения должен контролировать, что запущена только один его экземпляр.

Не по теме:

Извиняюсь, что без кода - нет под рукой инструментов. Может позже набросаю.

1
478 / 241 / 74
Регистрация: 25.05.2012
Сообщений: 1,138
Записей в блоге: 1
17.01.2023, 16:42  [ТС]
Цитата Сообщение от Uswer Посмотреть сообщение
Извиняюсь, что без кода - нет под рукой инструментов. Может позже набросаю.
Как раз-таки главный (концептуальный) ответ вы уже дали. Теперь новый челлендж для меня - грамотно реализовать предложенное решение.
0
478 / 241 / 74
Регистрация: 25.05.2012
Сообщений: 1,138
Записей в блоге: 1
19.01.2023, 12:46  [ТС]
Uswer, в общем, пока получилось изобрести такой велосипед

EventfulConcurrentQueue<T>
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    public sealed class EventfulConcurrentQueue<T>
    {
        private ConcurrentQueue<T> queue = new ConcurrentQueue<T>();
 
        public void Enqueue(T item)
        {
            queue.Enqueue(item);
            OnItemEqueued();
        }
        public bool TryDequeue(out T result)
        {
            var success = queue.TryDequeue(out result);
            if(success) 
            {
                // TODO - call OnItemDequeued(result); 
            }
 
            return success;
        }
 
        public event EventHandler ItemEnqueued;
        // TODO - add EventHandler ItemDequeued (+ ItemDequeuedEventArgs<T> class)
        // TODO - add void OnItemDequeued(T item)
        private void OnItemEqueued()
        {
            ItemEnqueued?.Invoke(this, EventArgs.Empty);
        }
 
        public int Count { get { return queue.Count; } }
    }


Notification
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
    public class Notification
    {
        public string Title { get; set; } = string.Empty;
        public string Text { get; set; } = string.Empty;
    }


NotificationEventArgs
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
    public sealed class NotificationEventArgs: EventArgs
    {
        public NotificationEventArgs(Notification notification)
        {
            Notification = notification;
        }
 
        public Notification Notification { get; private set; }
    }


NotificationManager
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
    public class NotificationManager
    {
        private EventfulConcurrentQueue<Notification> notifications = new EventfulConcurrentQueue<Notification>();
 
        public NotificationManager() 
        {
            notifications.ItemEnqueued += Notifications_ItemEnqueued;
            notificationTimer = new Timer(new TimerCallback(IssueNotification), null, Timeout.Infinite, Timeout.Infinite);
        }
 
        private void Notifications_ItemEnqueued(object? sender, EventArgs e)
        {
            if(!isBusy)
            {
                isBusy = true;
                IssueAllNotificationsAsync();
            }
        }
 
        public void Enqueue(Notification n)
        {
            notifications.Enqueue(n);
        }
 
        public event EventHandler<NotificationEventArgs> NotificationIssued;
        private Timer notificationTimer; 
        private bool isBusy = false;
        private bool delayStop = false;
 
        protected virtual void OnNotificationIssued(NotificationEventArgs e)
        {
            NotificationIssued?.Invoke(this, e);
        }
 
        private void IssueAllNotifications()
        {
            delayStop = true;
            notificationTimer.Change(0, 5000);
        }
 
        private async void IssueAllNotificationsAsync()
        {
            await Task.Run(() => IssueAllNotifications());
        }
 
        private void IssueNotification(object state)
        {
            Notification? n;
            if (notifications.TryDequeue(out n))
            {
                OnNotificationIssued(new NotificationEventArgs(n));
            }
 
            if(notifications.Count == 0 && !delayStop) //stop timer
            {
                notificationTimer.Change(Timeout.Infinite, Timeout.Infinite);
                isBusy = false;
            }
 
            if (notifications.Count == 0) //wait for last tick
            {
                delayStop = false;
            }
        }
    }


На форме подписываюсь на событие и в обработчике вызываю показ уведомления

C#
1
2
3
4
private void NotificationManager_NotificationIssued(object? sender, NotificationEventArgs e)
        {
            notifyIconMain.ShowBalloonTip(1000, е.Notification.Title, e.Notification.Text, ToolTipIcon.Info);
        }
В очередь уведомления помещаются методом .Enqueue()

C#
1
notificationManager.Enqueue(new Notification() { Title = "blah", Text = "blah blah" });
В принципе работает как задумывалось.
0
2287 / 1603 / 400
Регистрация: 26.06.2017
Сообщений: 4,756
Записей в блоге: 1
19.01.2023, 16:06
Лучший ответ Сообщение было отмечено NewOrdered как решение

Решение

NewOrdered, в принципе подход понятен, есть только одно замечание - это фиксированный интервал таймера = 5000. Причём этот интервал никак не увязывается с временем показа уведомления.
Если не сильно заморачиваться с универсальностью решения, то вот вариант на уровне формы. На форме должны быть: backgroundWorker1, notifyIcon1 и button1.
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace SequentialNotification
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }
 
    private Queue<MyNotify> notifies = new Queue<MyNotify>();
    private int notifyInterval = 3000;
    private bool notificationsAreShown;
 
    private async void ShowNotify()
    {
      if (!notificationsAreShown)
      {
        notificationsAreShown = true;
        while (notifies.Count > 0)
        {
          MyNotify currentNotify = notifies.Dequeue();
          notifyIcon1.ShowBalloonTip(notifyInterval, currentNotify.HeaderText, currentNotify.Message, ToolTipIcon.Info);
          await Task.Delay(notifyInterval); //неблокирующее ожидание
        }
        notificationsAreShown = false;
      }
    }
 
    private void button1_Click(object sender, EventArgs e)
    {
      backgroundWorker1.RunWorkerAsync();
    }
 
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
      backgroundWorker1.ReportProgress(0, new MyNotify() { HeaderText = "Not1", Message = "ups one!" });
      backgroundWorker1.ReportProgress(0, new MyNotify() { HeaderText = "Not2", Message = "ups two!" });
      backgroundWorker1.ReportProgress(0, new MyNotify() { HeaderText = "Not3", Message = "ups three!" });
    }
 
    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
      notifies.Enqueue((MyNotify)e.UserState);
      ShowNotify();
    }
  }
 
  public class MyNotify
  {
    public string Message { get; set; }
    public string HeaderText { get; set; }
  }
}

Если расширить класс MyNotify свойством NotifyTimeout, то у каждого уведомления может быть своя задержка отображения.
1
478 / 241 / 74
Регистрация: 25.05.2012
Сообщений: 1,138
Записей в блоге: 1
19.01.2023, 17:58  [ТС]
Цитата Сообщение от Uswer Посмотреть сообщение
есть только одно замечание - это фиксированный интервал таймера = 5000
ну пока это только прототип. Разумеется, интервал можно сделать настраиваемым.
Цитата Сообщение от Uswer Посмотреть сообщение
Причём этот интервал никак не увязывается с временем показа уведомления
Технически это даже не так важно, т.к. при показе нового уведомления текущее скрывается.

Таймер был выбран для того, чтобы не заморачиваться с ручным управлением очередью уведомлений. Для пущей универсальности планировал добавить интерфейс INotificationSubscriber с событием .NotificationDismissed. Тогда можно будет показывать следующее уведомление при закрытии пользователем текущего, не дожидаясь тика таймера. Но компонент NotifyIcon не такой гибкий как хотелось бы.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.01.2023, 17:58
Помогаю со студенческими работами здесь

Всплывающие уведомления
Всем доброго времени суток. В рамках курсовой работы пищу органайзер на WinAPI. Одной из функций должно быть напоминание пользователю о...

Всплывающие уведомления в Python
Есть ли в Python что-либо похожее на msgbox()? Возможно использование PyQt5. Если такая тема уже была, дайте ссылку.

Всплывающие уведомления Windows 10
Возможна ли разработка приложений, использующих всплывающие уведомления Windows 10, на С++? Если да, то какие файлы необходимо докачать для...

Всплывающие уведомления (Notifications) в Windows 10
Доброго времени суток! Подскажите пожалуйста, можно ли каким-то образом отслеживать всплывающие уведомления от других приложений и текст из...

Перестали появляться всплывающие уведомления от программы
Суть вопороса... Занимаюсь разработкой программ. Постояннно идет компиляция программы. С какого то времени моя программа перестала...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru