Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing the option to use multiple LifetimeSupervisors #120

Open
wants to merge 2 commits into
base: master-v2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
25 changes: 24 additions & 1 deletion Src/ToastNotifications/Display/NotificationsDisplaySupervisor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Threading;
using ToastNotifications.Core;
Expand All @@ -17,6 +18,7 @@ public class NotificationsDisplaySupervisor : IDisposable
private readonly IKeyboardEventHandler _keyboardEventHandler;

private INotificationsLifetimeSupervisor _lifetimeSupervisor;
private List<INotificationsLifetimeSupervisor> _lifetimeSupervisorList;
private NotificationsWindow _window;

public NotificationsDisplaySupervisor(Dispatcher dispatcher,
Expand All @@ -30,6 +32,8 @@ public NotificationsDisplaySupervisor(Dispatcher dispatcher,
_lifetimeSupervisor = lifetimeSupervisor;
_displayOptions = displayOptions;
_keyboardEventHandler = keyboardEventHandler;
_lifetimeSupervisorList = new List<INotificationsLifetimeSupervisor>();
_lifetimeSupervisorList.Add(lifetimeSupervisor);

_lifetimeSupervisor.ShowNotificationRequested += LifetimeSupervisorOnShowNotificationRequested;
_lifetimeSupervisor.CloseNotificationRequested += LifetimeSupervisorOnCloseNotificationRequested;
Expand All @@ -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();
Expand All @@ -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();
}

Expand Down
8 changes: 7 additions & 1 deletion Src/ToastNotifications/Display/NotificationsItemsControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,13 @@ private static T GetVisualChild<T>(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)
Expand Down
14 changes: 14 additions & 0 deletions Src/ToastNotifications/Lifetime/CountBasedLifetimeSupervisor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ShowNotificationEventArgs> ShowNotificationRequested;
public event EventHandler<CloseNotificationEventArgs> CloseNotificationRequested;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace ToastNotifications.Lifetime
{
public interface INotificationsLifetimeSupervisor : IDisposable
{
bool ContainsNotification(INotification notification);
void PushNotification(INotification notification);
void CloseNotification(INotification notification);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ShowNotificationEventArgs> ShowNotificationRequested;
public event EventHandler<CloseNotificationEventArgs> CloseNotificationRequested;
}
Expand Down
16 changes: 16 additions & 0 deletions Src/ToastNotifications/Notifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down