diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 150eb9f..979f1f0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,3 +4,57 @@ Any help, suggestions, finding issues, pull requests are really appreciated. If you crate an enhancement or bug fix to the library, and you would like to share it with the community, please send a pull request I will test, merge and release nuget + +Author: Alexandre José Heinen +Feature: Allowing multiple LifetimeSupervisors with different behaviors +I need to use two different LifetimeSupervisor, one with CountBasedLifetimeSupervisor and other with TimeAndCountBasedLifetimeSupervisor. If I create 2 separated Notifiers the notifications can be displayed over the notifications that are already opened. +For this I create a way to set multiple LifetimeSupervisors to same Notifiers and same DisplaySupervisor. +To work correctly the LifetimeSupervisors need to be cached, to pass the same instance. +Example of how to use: + +``` +private static Notifier GenerateNotifier(double notificationLifeTime, Corner notificationPosition) +{ + //here I check if the LifetimeSupervisor to use is based on time + //if it is null I create new instance + if (notificationLifeTime > 0 && _lifetimeTimeAndCount == null) + { + _lifetimeTimeAndCount = new TimeAndCountBasedLifetimeSupervisor( + notificationLifetime: TimeSpan.FromSeconds(notificationLifeTime), + maximumNotificationCount: MaximumNotificationCount.FromCount(5)); + } + + //here I check if the LifetimeSupervisor to use is based only on count + //if it is null I create new instance + if (notificationLifeTime == 0 && _lifetimeCount == null) + { + _lifetimeCount = new CountBasedLifetimeSupervisor(maximumNotificationCount: MaximumNotificationCount.FromCount(5)); + } + + //get the correct LifetimeSupervisor to use + INotificationsLifetimeSupervisor lifetimeSupervisor = notificationLifeTime > 0 ? (INotificationsLifetimeSupervisor)_lifetimeTimeAndCount : (INotificationsLifetimeSupervisor)_lifetimeCount; + + if (_notifier == null) + { + _notifier = new Notifier(cfg => + { + cfg.PositionProvider = new WindowPositionProvider( + parentWindow: Application.Current.MainWindow, + corner: notificationPosition, + offsetX: 10, + offsetY: 49); + + cfg.LifetimeSupervisor = lifetimeSupervisor; + + cfg.Dispatcher = Application.Current.Dispatcher; + }); + } + + //update the current LifetimeSupervisor in the notifier + _notifier.UpdateLifetimeSupervisor(lifetimeSupervisor); + + return _notifier; +} +``` + +In this case I'm not checking if the notificationLifeTime is different, but if you need you can cache into a dictionary with notificationLifeTime as the key. diff --git a/Src/ToastNotifications/Display/NotificationsDisplaySupervisor.cs b/Src/ToastNotifications/Display/NotificationsDisplaySupervisor.cs index e7117f3..e721234 100644 --- a/Src/ToastNotifications/Display/NotificationsDisplaySupervisor.cs +++ b/Src/ToastNotifications/Display/NotificationsDisplaySupervisor.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Windows; using System.Windows.Threading; using ToastNotifications.Core; @@ -17,6 +18,7 @@ public class NotificationsDisplaySupervisor : IDisposable private readonly IKeyboardEventHandler _keyboardEventHandler; private INotificationsLifetimeSupervisor _lifetimeSupervisor; + private List _lifetimeSupervisorList; private NotificationsWindow _window; public NotificationsDisplaySupervisor(Dispatcher dispatcher, @@ -30,6 +32,8 @@ public NotificationsDisplaySupervisor(Dispatcher dispatcher, _lifetimeSupervisor = lifetimeSupervisor; _displayOptions = displayOptions; _keyboardEventHandler = keyboardEventHandler; + _lifetimeSupervisorList = new List(); + _lifetimeSupervisorList.Add(lifetimeSupervisor); _lifetimeSupervisor.ShowNotificationRequested += LifetimeSupervisorOnShowNotificationRequested; _lifetimeSupervisor.CloseNotificationRequested += LifetimeSupervisorOnCloseNotificationRequested; @@ -44,6 +48,17 @@ public void DisplayNotification(INotification notification) Dispatch(() => InternalDisplayNotification(notification)); } + public void UpdateLifetimeSupervisor(INotificationsLifetimeSupervisor lifetimeSupervisor) + { + if (!_lifetimeSupervisorList.Contains(lifetimeSupervisor)) + { + _lifetimeSupervisorList.Add(lifetimeSupervisor); + lifetimeSupervisor.ShowNotificationRequested += LifetimeSupervisorOnShowNotificationRequested; + lifetimeSupervisor.CloseNotificationRequested += LifetimeSupervisorOnCloseNotificationRequested; + } + _lifetimeSupervisor = lifetimeSupervisor; + } + private void InternalDisplayNotification(INotification notification) { InitializeWindow(); @@ -61,7 +76,15 @@ private void Close(INotification notification) private void InternalClose(INotification notification) { - _lifetimeSupervisor.CloseNotification(notification); + //Needs to iterate all lifetimeSupervisor to check on what the notification was opened + foreach (var lifetimeSupervisor in _lifetimeSupervisorList) + { + if (lifetimeSupervisor.ContainsNotification(notification)) + { + lifetimeSupervisor.CloseNotification(notification); + break; + } + } UpdateWindowPosition(); } diff --git a/Src/ToastNotifications/Display/NotificationsItemsControl.cs b/Src/ToastNotifications/Display/NotificationsItemsControl.cs index 834be9f..561c70f 100644 --- a/Src/ToastNotifications/Display/NotificationsItemsControl.cs +++ b/Src/ToastNotifications/Display/NotificationsItemsControl.cs @@ -110,7 +110,13 @@ private static T GetVisualChild(DependencyObject parent) where T : Visual public void AddNotification(NotificationDisplayPart notification) { - Items.Add(notification); + //Can't find why notifications are tried to add more than one time + //Without this condition an error was thrown + if (notification.Parent == null) + { + Items.Add(notification); + } + } public void RemoveNotification(NotificationDisplayPart notification) diff --git a/Src/ToastNotifications/Lifetime/CountBasedLifetimeSupervisor.cs b/Src/ToastNotifications/Lifetime/CountBasedLifetimeSupervisor.cs index 981feaa..eb42e94 100644 --- a/Src/ToastNotifications/Lifetime/CountBasedLifetimeSupervisor.cs +++ b/Src/ToastNotifications/Lifetime/CountBasedLifetimeSupervisor.cs @@ -83,6 +83,20 @@ public void ClearMessages(IClearStrategy clearStrategy) } } + public bool ContainsNotification(INotification notification) + { + var enumerator = _notifications.GetEnumerator(); + while (enumerator.MoveNext()) + { + if (enumerator.Current.Value.Notification == notification) + { + return true; + } + } + + return false; + } + public event EventHandler ShowNotificationRequested; public event EventHandler CloseNotificationRequested; } diff --git a/Src/ToastNotifications/Lifetime/INotificationsLifeTimeSupervisor.cs b/Src/ToastNotifications/Lifetime/INotificationsLifeTimeSupervisor.cs index adc9b6e..805906b 100644 --- a/Src/ToastNotifications/Lifetime/INotificationsLifeTimeSupervisor.cs +++ b/Src/ToastNotifications/Lifetime/INotificationsLifeTimeSupervisor.cs @@ -7,6 +7,7 @@ namespace ToastNotifications.Lifetime { public interface INotificationsLifetimeSupervisor : IDisposable { + bool ContainsNotification(INotification notification); void PushNotification(INotification notification); void CloseNotification(INotification notification); diff --git a/Src/ToastNotifications/Lifetime/TimeAndCountBasedLifetimeSupervisor.cs b/Src/ToastNotifications/Lifetime/TimeAndCountBasedLifetimeSupervisor.cs index 810f66a..4ad45fa 100644 --- a/Src/ToastNotifications/Lifetime/TimeAndCountBasedLifetimeSupervisor.cs +++ b/Src/ToastNotifications/Lifetime/TimeAndCountBasedLifetimeSupervisor.cs @@ -145,6 +145,20 @@ public void ClearMessages(IClearStrategy clearStrategy) } } + public bool ContainsNotification(INotification notification) + { + var enumerator = _notifications.GetEnumerator(); + while (enumerator.MoveNext()) + { + if (enumerator.Current.Value.Notification == notification) + { + return true; + } + } + + return false; + } + public event EventHandler ShowNotificationRequested; public event EventHandler CloseNotificationRequested; } diff --git a/Src/ToastNotifications/Notifier.cs b/Src/ToastNotifications/Notifier.cs index 25ad268..5b4262d 100644 --- a/Src/ToastNotifications/Notifier.cs +++ b/Src/ToastNotifications/Notifier.cs @@ -76,6 +76,22 @@ public void ClearMessages(IClearStrategy clearStrategy) _lifetimeSupervisor?.ClearMessages(clearStrategy); } + public void UpdateLifetimeSupervisor(INotificationsLifetimeSupervisor lifetimeSupervisor) + { + if (_configuration != null) + { + lock (_syncRoot) + { + _configuration.LifetimeSupervisor = lifetimeSupervisor; + _lifetimeSupervisor = lifetimeSupervisor; + _lifetimeSupervisor.UseDispatcher(_configuration.Dispatcher); + + _displaySupervisor.UpdateLifetimeSupervisor(_lifetimeSupervisor); + } + + } + } + private bool _disposed = false; public object SyncRoot => _syncRoot;