From eabaa776cc450a0ae551d9d68f75643f48eadf1a Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 11 Jul 2023 16:29:41 +0200 Subject: [PATCH] feat: Customize Notifications --- .../ViewModels/NotificationViewModel.cs | 2 +- .../IManagedNotificationManager.cs | 13 +++- .../Notifications/NotificationCard.cs | 65 ++++++++++++++++++- .../WindowNotificationManager.cs | 24 +++---- 4 files changed, 88 insertions(+), 16 deletions(-) diff --git a/samples/ControlCatalog/ViewModels/NotificationViewModel.cs b/samples/ControlCatalog/ViewModels/NotificationViewModel.cs index bcbcb345ef..84a3c74dbf 100644 --- a/samples/ControlCatalog/ViewModels/NotificationViewModel.cs +++ b/samples/ControlCatalog/ViewModels/NotificationViewModel.cs @@ -11,7 +11,7 @@ namespace ControlCatalog.ViewModels { ShowCustomManagedNotificationCommand = MiniCommand.Create(() => { - NotificationManager?.Show(new NotificationViewModel() { Title = "Hey There!", Message = "Did you know that Avalonia now supports Custom In-Window Notifications?" , NotificationManager = NotificationManager}); + NotificationManager?.Show(new NotificationViewModel() { Title = "Hey There!", Message = "Did you know that Avalonia now supports Custom In-Window Notifications?" , NotificationManager = NotificationManager}, NotificationType.Warning); }); ShowManagedNotificationCommand = MiniCommand.Create(() => diff --git a/src/Avalonia.Controls/Notifications/IManagedNotificationManager.cs b/src/Avalonia.Controls/Notifications/IManagedNotificationManager.cs index b2e6e9e80b..8d1cb644be 100644 --- a/src/Avalonia.Controls/Notifications/IManagedNotificationManager.cs +++ b/src/Avalonia.Controls/Notifications/IManagedNotificationManager.cs @@ -1,4 +1,5 @@ -using Avalonia.Metadata; +using System; +using Avalonia.Metadata; namespace Avalonia.Controls.Notifications { @@ -18,6 +19,14 @@ namespace Avalonia.Controls.Notifications /// Shows a notification. /// /// The content to be displayed. - void Show(object content); + /// The of the notification. + /// the expiration time of the notification after which it will automatically close. If the value is then the notification will remain open until the user closes it. + /// an Action to be run when the notification is clicked. + /// an Action to be run when the notification is closed. + void Show(object content, + NotificationType type = NotificationType.Information, + TimeSpan? expiration = null, + Action? onClick = null, + Action? onClose = null); } } diff --git a/src/Avalonia.Controls/Notifications/NotificationCard.cs b/src/Avalonia.Controls/Notifications/NotificationCard.cs index 7d5b6cc0ca..da9e15a7f3 100644 --- a/src/Avalonia.Controls/Notifications/NotificationCard.cs +++ b/src/Avalonia.Controls/Notifications/NotificationCard.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using Avalonia.Reactive; using Avalonia.Controls.Metadata; @@ -61,6 +61,7 @@ namespace Avalonia.Controls.Notifications } } }); + UpdateNotificationType(); } /// @@ -93,6 +94,21 @@ namespace Avalonia.Controls.Notifications public static readonly StyledProperty IsClosedProperty = AvaloniaProperty.Register(nameof(IsClosed)); + /// + /// Gets or sets the type of the notification + /// + public NotificationType NotificationType + { + get { return GetValue(NotificationTypeProperty); } + set { SetValue(NotificationTypeProperty, value); } + } + + /// + /// Defines the property + /// + public static readonly StyledProperty NotificationTypeProperty = + AvaloniaProperty.Register(nameof(NotificationType)); + /// /// Defines the event. /// @@ -163,5 +179,52 @@ namespace Avalonia.Controls.Notifications IsClosing = true; } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) + { + base.OnPropertyChanged(e); + + if (e.Property == ContentProperty && e.NewValue is INotification notification) + { + SetValue(NotificationTypeProperty, notification.Type); + } + + if (e.Property == NotificationTypeProperty) + { + UpdateNotificationType(); + } + + if (e.Property == IsClosedProperty) + { + if (!IsClosing && !IsClosed) + { + return; + } + + RaiseEvent(new RoutedEventArgs(NotificationClosedEvent)); + } + } + + private void UpdateNotificationType() + { + switch (NotificationType) + { + case NotificationType.Error: + PseudoClasses.Add(":error"); + break; + + case NotificationType.Information: + PseudoClasses.Add(":information"); + break; + + case NotificationType.Success: + PseudoClasses.Add(":success"); + break; + + case NotificationType.Warning: + PseudoClasses.Add(":warning"); + break; + } + } } } diff --git a/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs b/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs index b03099f750..d764f2bd78 100644 --- a/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs +++ b/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs @@ -80,32 +80,32 @@ namespace Avalonia.Controls.Notifications /// public void Show(INotification content) { - Show(content as object); + Show(content, content.Type, content.Expiration, content.OnClick, content.OnClose); } /// - public async void Show(object content) + public async void Show(object content, + NotificationType type = NotificationType.Information, + TimeSpan? expiration = null, + Action? onClick = null, + Action? onClose = null) { - var notification = content as INotification; - var notificationControl = new NotificationCard { - Content = content + Content = content, + NotificationType = type }; notificationControl.NotificationClosed += (sender, args) => { - notification?.OnClose?.Invoke(); + onClose?.Invoke(); _items?.Remove(sender); }; notificationControl.PointerPressed += (sender, args) => { - if (notification != null && notification.OnClick != null) - { - notification.OnClick.Invoke(); - } + onClick?.Invoke(); (sender as NotificationCard)?.Close(); }; @@ -117,12 +117,12 @@ namespace Avalonia.Controls.Notifications _items.OfType().First(i => !i.IsClosing).Close(); } - if (notification != null && notification.Expiration == TimeSpan.Zero) + if (expiration == TimeSpan.Zero) { return; } - await Task.Delay(notification?.Expiration ?? TimeSpan.FromSeconds(5)); + await Task.Delay(expiration ?? TimeSpan.FromSeconds(5)); notificationControl.Close(); }