diff --git a/api/Avalonia.nupkg.xml b/api/Avalonia.nupkg.xml index 00ec23467d..27aab099fa 100644 --- a/api/Avalonia.nupkg.xml +++ b/api/Avalonia.nupkg.xml @@ -1105,4 +1105,22 @@ baseline/netstandard2.0/Avalonia.Base.dll target/netstandard2.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Controls.Notifications.IManagedNotificationManager.Close(System.Object) + baseline/netstandard2.0/Avalonia.Controls.dll + target/netstandard2.0/Avalonia.Controls.dll + + + CP0006 + M:Avalonia.Controls.Notifications.INotificationManager.Close(Avalonia.Controls.Notifications.INotification) + baseline/netstandard2.0/Avalonia.Controls.dll + target/netstandard2.0/Avalonia.Controls.dll + + + CP0006 + M:Avalonia.Controls.Notifications.INotificationManager.CloseAll + baseline/netstandard2.0/Avalonia.Controls.dll + target/netstandard2.0/Avalonia.Controls.dll + \ No newline at end of file diff --git a/src/Avalonia.Controls/Notifications/IManagedNotificationManager.cs b/src/Avalonia.Controls/Notifications/IManagedNotificationManager.cs index bd57f3a86f..202ca053bc 100644 --- a/src/Avalonia.Controls/Notifications/IManagedNotificationManager.cs +++ b/src/Avalonia.Controls/Notifications/IManagedNotificationManager.cs @@ -1,4 +1,4 @@ -using System; +using System.Threading; using Avalonia.Metadata; namespace Avalonia.Controls.Notifications @@ -20,5 +20,11 @@ namespace Avalonia.Controls.Notifications /// /// The content to be displayed. void Show(object content); + + /// + /// Closes a notification. + /// + /// The content to be closed. + void Close(object content); } } diff --git a/src/Avalonia.Controls/Notifications/INotificationManager.cs b/src/Avalonia.Controls/Notifications/INotificationManager.cs index 5fa479f2c3..c4725c5f68 100644 --- a/src/Avalonia.Controls/Notifications/INotificationManager.cs +++ b/src/Avalonia.Controls/Notifications/INotificationManager.cs @@ -14,5 +14,16 @@ namespace Avalonia.Controls.Notifications /// /// The notification to be displayed. void Show(INotification notification); + + /// + /// Closes a notification. + /// + /// The notification to be closed. + void Close(INotification notification); + + /// + /// Closes all notifications. + /// + void CloseAll(); } } diff --git a/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs b/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs index 31e262d99a..4500be6136 100644 --- a/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs +++ b/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs @@ -3,7 +3,6 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Avalonia.Collections; using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Threading; @@ -19,6 +18,8 @@ namespace Avalonia.Controls.Notifications public class WindowNotificationManager : TemplatedControl, IManagedNotificationManager { private IList? _items; + private readonly Dictionary _notificationCards = new (); + /// /// Defines the property. /// @@ -103,7 +104,7 @@ namespace Avalonia.Controls.Notifications Show(content, NotificationType.Information); } } - + /// /// Shows a Notification /// @@ -121,7 +122,7 @@ namespace Avalonia.Controls.Notifications string[]? classes = null) { Dispatcher.UIThread.VerifyAccess(); - + var notificationControl = new NotificationCard { Content = content, @@ -136,12 +137,13 @@ namespace Avalonia.Controls.Notifications notificationControl.Classes.Add(@class); } } - + notificationControl.NotificationClosed += (sender, args) => { onClose?.Invoke(); _items?.Remove(sender); + _notificationCards.Remove(content); }; notificationControl.PointerPressed += (sender, args) => @@ -154,6 +156,7 @@ namespace Avalonia.Controls.Notifications Dispatcher.UIThread.Post(() => { _items?.Add(notificationControl); + _notificationCards.Add(content, notificationControl); if (_items?.OfType().Count(i => !i.IsClosing) > MaxItems) { @@ -169,6 +172,43 @@ namespace Avalonia.Controls.Notifications await Task.Delay(expiration ?? TimeSpan.FromSeconds(5)); notificationControl.Close(); + + _notificationCards.Remove(content); + } + + /// + public void Close(INotification notification) + { + Dispatcher.UIThread.VerifyAccess(); + + if (_notificationCards.Remove(notification, out var notificationCard)) + { + notificationCard.Close(); + } + } + + /// + public void Close(object content) + { + Dispatcher.UIThread.VerifyAccess(); + + if (_notificationCards.Remove(content, out var notificationCard)) + { + notificationCard.Close(); + } + } + + /// + public void CloseAll() + { + Dispatcher.UIThread.VerifyAccess(); + + foreach (var kvp in _notificationCards) + { + kvp.Value.Close(); + } + + _notificationCards.Clear(); } protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) @@ -181,6 +221,13 @@ namespace Avalonia.Controls.Notifications } } + protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnDetachedFromVisualTree(e); + + _notificationCards.Clear(); + } + /// /// Installs the within the ///