Merge pull request #626 from irihitech/manager

Add TryGetXXManager to WindowXXManager
This commit is contained in:
Dong Bin
2025-03-28 11:58:45 +08:00
committed by GitHub
7 changed files with 74 additions and 21 deletions

View File

@@ -1,8 +1,12 @@
using System;
using System.Diagnostics;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using Ursa.Controls; using Ursa.Controls;
using WindowNotificationManager = Ursa.Controls.WindowNotificationManager;
namespace Ursa.Demo.Dialogs; namespace Ursa.Demo.Dialogs;
@@ -20,17 +24,14 @@ public partial class CustomDemoDialog : UserControl
base.OnAttachedToVisualTree(e); base.OnAttachedToVisualTree(e);
_viewModel = this.DataContext as CustomDemoDialogViewModel; _viewModel = this.DataContext as CustomDemoDialogViewModel;
var visualLayerManager = this.FindAncestorOfType<VisualLayerManager>(); var visualLayerManager = this.FindAncestorOfType<VisualLayerManager>();
if (visualLayerManager is not null && _viewModel is not null) if (_viewModel == null) return;
{ _viewModel.NotificationManager =
_viewModel.NotificationManager = new WindowNotificationManager(visualLayerManager) { MaxItems = 3 }; WindowNotificationManager.TryGetNotificationManager(visualLayerManager, out var notificationManager)
_viewModel.ToastManager = new WindowToastManager(visualLayerManager) { MaxItems = 3 }; ? notificationManager
} : new WindowNotificationManager(visualLayerManager) { MaxItems = 3 };
} _viewModel.ToastManager = WindowToastManager.TryGetToastManager(visualLayerManager, out var toastManager)
? toastManager
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) : new WindowToastManager(visualLayerManager) { MaxItems = 3 };
{ Debug.Assert(WindowNotificationManager.TryGetNotificationManager(visualLayerManager, out _));
base.OnDetachedFromVisualTree(e);
_viewModel?.NotificationManager?.Uninstall();
_viewModel?.ToastManager?.Uninstall();
} }
} }

View File

@@ -1,6 +1,5 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.LogicalTree;
using Ursa.Controls; using Ursa.Controls;
using Ursa.Demo.ViewModels; using Ursa.Demo.ViewModels;
@@ -21,12 +20,11 @@ public partial class NotificationDemo : UserControl
{ {
base.OnAttachedToVisualTree(e); base.OnAttachedToVisualTree(e);
var topLevel = TopLevel.GetTopLevel(this); var topLevel = TopLevel.GetTopLevel(this);
_viewModel.NotificationManager = new WindowNotificationManager(topLevel) { MaxItems = 3 };
}
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e) WindowNotificationManager.TryGetNotificationManager(topLevel, out var manager);
{ if (manager is not null)
base.OnDetachedFromLogicalTree(e); {
_viewModel.NotificationManager?.Uninstall(); _viewModel.NotificationManager = manager;
}
} }
} }

View File

@@ -1,16 +1,19 @@
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using Avalonia; using Avalonia;
using Avalonia.Controls.Notifications;
using Avalonia.Styling; using Avalonia.Styling;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging;
using Ursa.Controls;
using Ursa.Themes.Semi; using Ursa.Themes.Semi;
using Notification = Ursa.Controls.Notification;
using WindowNotificationManager = Ursa.Controls.WindowNotificationManager;
namespace Ursa.Demo.ViewModels; namespace Ursa.Demo.ViewModels;
public partial class MainViewViewModel : ViewModelBase public partial class MainViewViewModel : ViewModelBase
{ {
public WindowNotificationManager? NotificationManager { get; set; }
public MenuViewModel Menus { get; set; } = new MenuViewModel(); public MenuViewModel Menus { get; set; } = new MenuViewModel();
private object? _content; private object? _content;
@@ -107,6 +110,10 @@ public partial class MainViewViewModel : ViewModelBase
if (app is not null) if (app is not null)
{ {
app.RequestedThemeVariant = newValue.Theme; app.RequestedThemeVariant = newValue.Theme;
NotificationManager?.Show(
new Notification("Theme changed", $"Theme changed to {newValue.Name}"),
type: NotificationType.Success,
classes: ["Light"]);
} }
} }

View File

@@ -1,11 +1,28 @@
using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Ursa.Controls;
using Ursa.Demo.ViewModels;
namespace Ursa.Demo.Views; namespace Ursa.Demo.Views;
public partial class MainView : UserControl public partial class MainView : UserControl
{ {
private MainViewViewModel? _viewModel;
public MainView() public MainView()
{ {
InitializeComponent(); 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;
}
}
} }

View File

@@ -5,9 +5,12 @@ namespace Ursa.Demo.Views;
public partial class MainWindow : UrsaWindow public partial class MainWindow : UrsaWindow
{ {
public WindowNotificationManager? NotificationManager { get; set; }
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
NotificationManager = new WindowNotificationManager(this) { MaxItems = 3 };
} }
protected override async Task<bool> CanClose() protected override async Task<bool> CanClose()

View File

@@ -5,6 +5,7 @@ using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.Threading; using Avalonia.Threading;
using Avalonia.VisualTree;
namespace Ursa.Controls; namespace Ursa.Controls;
@@ -69,6 +70,18 @@ public class WindowNotificationManager : WindowMessageManager, INotificationMana
VerticalAlignmentProperty.OverrideDefaultValue<WindowNotificationManager>(VerticalAlignment.Stretch); VerticalAlignmentProperty.OverrideDefaultValue<WindowNotificationManager>(VerticalAlignment.Stretch);
} }
/// <summary>
/// Tries to get the <see cref="WindowNotificationManager"/> from a <see cref="Visual"/>.
/// </summary>
/// <param name="visual">A <see cref="Visual"/> that is either a <see cref="Window"/> or a <see cref="VisualLayerManager"/>.</param>
/// <param name="manager">The existing <see cref="WindowNotificationManager"/> if found, or null if not found.</param>
/// <returns>True if a <see cref="WindowNotificationManager"/> is found; otherwise, false.</returns>
public static bool TryGetNotificationManager(Visual? visual, out WindowNotificationManager? manager)
{
manager = visual?.FindDescendantOfType<WindowNotificationManager>();
return manager is not null;
}
/// <inheritdoc/> /// <inheritdoc/>
public void Show(INotification content) public void Show(INotification content)
{ {

View File

@@ -1,7 +1,9 @@
using Avalonia.Controls; using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Notifications; using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Threading; using Avalonia.Threading;
using Avalonia.VisualTree;
namespace Ursa.Controls; namespace Ursa.Controls;
@@ -33,6 +35,18 @@ public class WindowToastManager : WindowMessageManager, IToastManager
{ {
} }
/// <summary>
/// Tries to get the <see cref="WindowToastManager"/> from a <see cref="Window"/> or <see cref="VisualLayerManager"/>.
/// </summary>
/// <param name="visual">A <see cref="Visual"/> that is either a <see cref="Window"/> or a <see cref="VisualLayerManager"/>.</param>
/// <param name="manager">The existing <see cref="WindowToastManager"/> if found, or null if not found.</param>
/// <returns>True if a <see cref="WindowToastManager"/> is found; otherwise, false.</returns>
public static bool TryGetToastManager(Visual? visual, out WindowToastManager? manager)
{
manager = visual?.FindDescendantOfType<WindowToastManager>();
return manager is not null;
}
/// <inheritdoc/> /// <inheritdoc/>
public void Show(IToast content) public void Show(IToast content)
{ {