From ed3657452e02cd57a49f7a1d406f22695294631c Mon Sep 17 00:00:00 2001 From: Kemp Calalo Date: Tue, 4 Jun 2019 11:42:51 +0200 Subject: [PATCH] Fix for issue#12, toast window stays at app switcher even no notification is displayed. --- Notifications.Wpf/Controls/Notification.cs | 28 +++++++++---- Notifications.Wpf/NotificationManager.cs | 7 +++- .../Utils/VisualTreeHelperExtensions.cs | 42 ++++++++++++++++++- 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/Notifications.Wpf/Controls/Notification.cs b/Notifications.Wpf/Controls/Notification.cs index 58ab8aa..3a7416c 100644 --- a/Notifications.Wpf/Controls/Notification.cs +++ b/Notifications.Wpf/Controls/Notification.cs @@ -52,7 +52,7 @@ public static void SetCloseOnClick(DependencyObject obj, bool value) } public static readonly DependencyProperty CloseOnClickProperty = - DependencyProperty.RegisterAttached("CloseOnClick", typeof(bool), typeof(Notification), new FrameworkPropertyMetadata(false,CloseOnClickChanged)); + DependencyProperty.RegisterAttached("CloseOnClick", typeof(bool), typeof(Notification), new FrameworkPropertyMetadata(false, CloseOnClickChanged)); private static void CloseOnClickChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) { @@ -72,7 +72,7 @@ private static void CloseOnClickChanged(DependencyObject dependencyObject, Depen notification?.Close(); }; } - } + } public override void OnApplyTemplate() { @@ -80,17 +80,17 @@ public override void OnApplyTemplate() var closeButton = GetTemplateChild("PART_CloseButton") as Button; if (closeButton != null) closeButton.Click += OnCloseButtonOnClick; - + var storyboards = Template.Triggers.OfType().FirstOrDefault(t => t.RoutedEvent == NotificationCloseInvokedEvent)?.Actions.OfType().Select(a => a.Storyboard); _closingAnimationTime = new TimeSpan(storyboards?.Max(s => Math.Min((s.Duration.HasTimeSpan ? s.Duration.TimeSpan + (s.BeginTime ?? TimeSpan.Zero) : TimeSpan.MaxValue).Ticks, s.Children.Select(ch => ch.Duration.TimeSpan + (s.BeginTime ?? TimeSpan.Zero)).Max().Ticks)) ?? 0); - + } private void OnCloseButtonOnClick(object sender, RoutedEventArgs args) { var button = sender as Button; if (button == null) return; - + button.Click -= OnCloseButtonOnClick; Close(); } @@ -102,12 +102,22 @@ public async void Close() { return; } - + IsClosing = true; - + RaiseEvent(new RoutedEventArgs(NotificationCloseInvokedEvent)); await Task.Delay(_closingAnimationTime); RaiseEvent(new RoutedEventArgs(NotificationClosedEvent)); - } - } + + var currentWindow = Application.Current.Windows.OfType().FirstOrDefault(x => x.Title.Equals("ToastWindow")); + + var notificationCount = VisualTreeHelperExtensions.GetActiveNotificationCount(currentWindow); + + if (notificationCount == 0) + currentWindow?.Hide(); + + } + + + } } diff --git a/Notifications.Wpf/NotificationManager.cs b/Notifications.Wpf/NotificationManager.cs index 0e8091e..bde766c 100644 --- a/Notifications.Wpf/NotificationManager.cs +++ b/Notifications.Wpf/NotificationManager.cs @@ -50,10 +50,15 @@ public void Show(object content, string areaName = "", TimeSpan? expirationTime _window.Show(); } + if (Areas != null && !_window.IsVisible) + _window.Show(); + foreach (var area in Areas.Where(a => a.Name == areaName)) { - area.Show(content, (TimeSpan) expirationTime, onClick, onClose); + area.Show(content, (TimeSpan)expirationTime, onClick, onClose); } + + } internal static void AddArea(NotificationArea area) diff --git a/Notifications.Wpf/Utils/VisualTreeHelperExtensions.cs b/Notifications.Wpf/Utils/VisualTreeHelperExtensions.cs index e930e92..83ef1ba 100644 --- a/Notifications.Wpf/Utils/VisualTreeHelperExtensions.cs +++ b/Notifications.Wpf/Utils/VisualTreeHelperExtensions.cs @@ -10,13 +10,16 @@ namespace Notifications.Wpf.Utils { internal class VisualTreeHelperExtensions { + + private static List _activeControls = new List(); + public static T GetParent(DependencyObject child) where T : DependencyObject { var parent = VisualTreeHelper.GetParent(child); - + if (parent == null) return null; - var tParent = parent as T; + var tParent = parent as T; if (tParent != null) { return tParent; @@ -24,5 +27,40 @@ public static T GetParent(DependencyObject child) where T : DependencyObject return GetParent(parent); } + + public static int GetActiveNotificationCount(Visual element) + { + if (element == null) + { + throw new ArgumentNullException(String.Format("Element {0} is null !", element.ToString())); + } + + _activeControls.Clear(); + + GetControlsList(element, 0); + + var count = _activeControls.Count(x => x.GetType().Name.Equals("Notification")); + + return count; + } + + private static void GetControlsList(Visual control, int level) + { + const int indent = 4; + int ChildNumber = VisualTreeHelper.GetChildrenCount(control); + + for (int i = 0; i <= ChildNumber - 1; i++) + { + Visual v = (Visual)VisualTreeHelper.GetChild(control, i); + + _activeControls.Add(v); + + if (VisualTreeHelper.GetChildrenCount(v) > 0) + { + GetControlsList(v, level + 1); + } + } + } + } }