diff --git a/demo/Ursa.Demo/Dialogs/CustomDemoDialog.axaml.cs b/demo/Ursa.Demo/Dialogs/CustomDemoDialog.axaml.cs index 1cbc0ce..7e5cd07 100644 --- a/demo/Ursa.Demo/Dialogs/CustomDemoDialog.axaml.cs +++ b/demo/Ursa.Demo/Dialogs/CustomDemoDialog.axaml.cs @@ -1,8 +1,12 @@ +using System; +using System.Diagnostics; using Avalonia; using Avalonia.Controls; +using Avalonia.Controls.Notifications; using Avalonia.Controls.Primitives; using Avalonia.VisualTree; using Ursa.Controls; +using WindowNotificationManager = Ursa.Controls.WindowNotificationManager; namespace Ursa.Demo.Dialogs; @@ -20,17 +24,14 @@ public partial class CustomDemoDialog : UserControl base.OnAttachedToVisualTree(e); _viewModel = this.DataContext as CustomDemoDialogViewModel; var visualLayerManager = this.FindAncestorOfType(); - if (visualLayerManager is not null && _viewModel is not null) - { - _viewModel.NotificationManager = new WindowNotificationManager(visualLayerManager) { MaxItems = 3 }; - _viewModel.ToastManager = new WindowToastManager(visualLayerManager) { MaxItems = 3 }; - } - } - - protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnDetachedFromVisualTree(e); - _viewModel?.NotificationManager?.Uninstall(); - _viewModel?.ToastManager?.Uninstall(); + if (_viewModel == null) return; + _viewModel.NotificationManager = + WindowNotificationManager.TryGetNotificationManager(visualLayerManager, out var notificationManager) + ? notificationManager + : new WindowNotificationManager(visualLayerManager) { MaxItems = 3 }; + _viewModel.ToastManager = WindowToastManager.TryGetToastManager(visualLayerManager, out var toastManager) + ? toastManager + : new WindowToastManager(visualLayerManager) { MaxItems = 3 }; + Debug.Assert(WindowNotificationManager.TryGetNotificationManager(visualLayerManager, out _)); } } \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/NotificationDemo.axaml.cs b/demo/Ursa.Demo/Pages/NotificationDemo.axaml.cs index 31d0e78..ccdb5d0 100644 --- a/demo/Ursa.Demo/Pages/NotificationDemo.axaml.cs +++ b/demo/Ursa.Demo/Pages/NotificationDemo.axaml.cs @@ -1,6 +1,5 @@ using Avalonia; using Avalonia.Controls; -using Avalonia.LogicalTree; using Ursa.Controls; using Ursa.Demo.ViewModels; @@ -21,12 +20,11 @@ public partial class NotificationDemo : UserControl { base.OnAttachedToVisualTree(e); var topLevel = TopLevel.GetTopLevel(this); - _viewModel.NotificationManager = new WindowNotificationManager(topLevel) { MaxItems = 3 }; - } - protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e) - { - base.OnDetachedFromLogicalTree(e); - _viewModel.NotificationManager?.Uninstall(); + WindowNotificationManager.TryGetNotificationManager(topLevel, out var manager); + if (manager is not null) + { + _viewModel.NotificationManager = manager; + } } } \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs index 161df53..181c82d 100644 --- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs @@ -1,16 +1,19 @@ using System; using System.Collections.ObjectModel; using Avalonia; +using Avalonia.Controls.Notifications; using Avalonia.Styling; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Messaging; -using Ursa.Controls; using Ursa.Themes.Semi; +using Notification = Ursa.Controls.Notification; +using WindowNotificationManager = Ursa.Controls.WindowNotificationManager; namespace Ursa.Demo.ViewModels; public partial class MainViewViewModel : ViewModelBase { + public WindowNotificationManager? NotificationManager { get; set; } public MenuViewModel Menus { get; set; } = new MenuViewModel(); private object? _content; @@ -107,6 +110,10 @@ public partial class MainViewViewModel : ViewModelBase if (app is not null) { app.RequestedThemeVariant = newValue.Theme; + NotificationManager?.Show( + new Notification("Theme changed", $"Theme changed to {newValue.Name}"), + type: NotificationType.Success, + classes: ["Light"]); } } diff --git a/demo/Ursa.Demo/Views/MainView.axaml.cs b/demo/Ursa.Demo/Views/MainView.axaml.cs index 8ee2660..c7353e1 100644 --- a/demo/Ursa.Demo/Views/MainView.axaml.cs +++ b/demo/Ursa.Demo/Views/MainView.axaml.cs @@ -1,11 +1,28 @@ +using Avalonia; using Avalonia.Controls; +using Ursa.Controls; +using Ursa.Demo.ViewModels; namespace Ursa.Demo.Views; public partial class MainView : UserControl { + private MainViewViewModel? _viewModel; + public MainView() { InitializeComponent(); } + + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnAttachedToVisualTree(e); + _viewModel = DataContext as MainViewViewModel; + var topLevel = TopLevel.GetTopLevel(this); + WindowNotificationManager.TryGetNotificationManager(topLevel, out var manager); + if (manager is not null && _viewModel is not null) + { + _viewModel.NotificationManager = manager; + } + } } \ No newline at end of file diff --git a/demo/Ursa.Demo/Views/MainWindow.axaml.cs b/demo/Ursa.Demo/Views/MainWindow.axaml.cs index 3edd6fe..1aa93a4 100644 --- a/demo/Ursa.Demo/Views/MainWindow.axaml.cs +++ b/demo/Ursa.Demo/Views/MainWindow.axaml.cs @@ -5,9 +5,12 @@ namespace Ursa.Demo.Views; public partial class MainWindow : UrsaWindow { + public WindowNotificationManager? NotificationManager { get; set; } + public MainWindow() { InitializeComponent(); + NotificationManager = new WindowNotificationManager(this) { MaxItems = 3 }; } protected override async Task CanClose() diff --git a/src/Ursa/Controls/Notification/WindowNotificationManager.cs b/src/Ursa/Controls/Notification/WindowNotificationManager.cs index 8b9e41e..3613076 100644 --- a/src/Ursa/Controls/Notification/WindowNotificationManager.cs +++ b/src/Ursa/Controls/Notification/WindowNotificationManager.cs @@ -5,6 +5,7 @@ using Avalonia.Controls.Notifications; using Avalonia.Controls.Primitives; using Avalonia.Layout; using Avalonia.Threading; +using Avalonia.VisualTree; namespace Ursa.Controls; @@ -69,6 +70,18 @@ public class WindowNotificationManager : WindowMessageManager, INotificationMana VerticalAlignmentProperty.OverrideDefaultValue(VerticalAlignment.Stretch); } + /// + /// Tries to get the from a . + /// + /// A that is either a or a . + /// The existing if found, or null if not found. + /// True if a is found; otherwise, false. + public static bool TryGetNotificationManager(Visual? visual, out WindowNotificationManager? manager) + { + manager = visual?.FindDescendantOfType(); + return manager is not null; + } + /// public void Show(INotification content) { diff --git a/src/Ursa/Controls/Toast/WindowToastManager.cs b/src/Ursa/Controls/Toast/WindowToastManager.cs index 312c7df..a2b037a 100644 --- a/src/Ursa/Controls/Toast/WindowToastManager.cs +++ b/src/Ursa/Controls/Toast/WindowToastManager.cs @@ -1,7 +1,9 @@ -using Avalonia.Controls; +using Avalonia; +using Avalonia.Controls; using Avalonia.Controls.Notifications; using Avalonia.Controls.Primitives; using Avalonia.Threading; +using Avalonia.VisualTree; namespace Ursa.Controls; @@ -33,6 +35,18 @@ public class WindowToastManager : WindowMessageManager, IToastManager { } + /// + /// Tries to get the from a or . + /// + /// A that is either a or a . + /// The existing if found, or null if not found. + /// True if a is found; otherwise, false. + public static bool TryGetToastManager(Visual? visual, out WindowToastManager? manager) + { + manager = visual?.FindDescendantOfType(); + return manager is not null; + } + /// public void Show(IToast content) {