diff --git a/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs b/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs
index 889e17ba03..cb7ade44b3 100644
--- a/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs
+++ b/src/Avalonia.Controls/Notifications/WindowNotificationManager.cs
@@ -1,7 +1,9 @@
using System;
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;
@@ -17,8 +19,6 @@ namespace Avalonia.Controls.Notifications
public class WindowNotificationManager : TemplatedControl, IManagedNotificationManager
{
private IList? _items;
- private AdornerLayer? adornerLayer;
-
///
/// Defines the property.
///
@@ -49,34 +49,14 @@ namespace Avalonia.Controls.Notifications
get { return GetValue(MaxItemsProperty); }
set { SetValue(MaxItemsProperty, value); }
}
-
- ///
- /// Defines the property
- ///
- public static readonly DirectProperty HostProperty =
- AvaloniaProperty.RegisterDirect(
- nameof(Host),
- o => o.Host,
- (o, v) => o.Host = v);
-
- private Visual? _Host;
-
- ///
- /// The Host that this NotificationManger should register to. If the Host is null, the Parent will be used.
- ///
- public Visual? Host
- {
- get { return _Host; }
- set { SetAndRaise(HostProperty, ref _Host, value); }
- }
///
/// Initializes a new instance of the class.
///
/// The TopLevel that will host the control.
- public WindowNotificationManager(TopLevel? host) : this()
+ public WindowNotificationManager(TopLevel host) : this()
{
- Host = host;
+ InstallFromTopLevel(host);
}
///
@@ -137,6 +117,8 @@ namespace Avalonia.Controls.Notifications
Action? onClose = null,
string[]? classes = null)
{
+ Dispatcher.UIThread.VerifyAccess();
+
var notificationControl = new NotificationCard
{
Content = content,
@@ -194,38 +176,34 @@ namespace Avalonia.Controls.Notifications
{
UpdatePseudoClasses(change.GetNewValue());
}
-
- if (change.Property == HostProperty)
- {
- Install();
- }
}
///
/// Installs the within the
///
- private void Install()
+ private void InstallFromTopLevel(TopLevel topLevel)
{
- // unregister from AdornerLayer if this control was already installed
- if (adornerLayer is not null && !adornerLayer.Children.Contains(this))
+ topLevel.TemplateApplied += TopLevelOnTemplateApplied;
+ var adorner = topLevel.FindDescendantOfType()?.AdornerLayer;
+ if (adorner is not null)
{
- adornerLayer.Children.Remove(this);
+ adorner.Children.Add(this);
+ AdornerLayer.SetAdornedElement(this, adorner);
}
-
- // Try to get the host. If host was null, use the TopLevel instead.
- var host = Host ?? Parent as Visual;
-
- if (host is null) throw new InvalidOperationException("NotificationControl cannot be installed. Host was not found.");
-
- adornerLayer = host is TopLevel
- ? host.FindDescendantOfType()?.AdornerLayer
- : AdornerLayer.GetAdornerLayer(host);
+ }
- if (adornerLayer is not null)
+ private void TopLevelOnTemplateApplied(object? sender, TemplateAppliedEventArgs e)
+ {
+ if (Parent is AdornerLayer adornerLayer)
{
- adornerLayer.Children.Add(this);
- AdornerLayer.SetAdornedElement(this, adornerLayer);
+ adornerLayer.Children.Remove(this);
+ AdornerLayer.SetAdornedElement(this, null);
}
+
+ // Reinstall notification manager on template reapplied.
+ var topLevel = (TopLevel)sender!;
+ topLevel.TemplateApplied -= TopLevelOnTemplateApplied;
+ InstallFromTopLevel(topLevel);
}
private void UpdatePseudoClasses(NotificationPosition position)
diff --git a/src/Avalonia.Controls/Primitives/AdornerLayer.cs b/src/Avalonia.Controls/Primitives/AdornerLayer.cs
index 37c46e1e7d..f21b608667 100644
--- a/src/Avalonia.Controls/Primitives/AdornerLayer.cs
+++ b/src/Avalonia.Controls/Primitives/AdornerLayer.cs
@@ -61,7 +61,7 @@ namespace Avalonia.Controls.Primitives
return adorner.GetValue(AdornedElementProperty);
}
- public static void SetAdornedElement(Visual adorner, Visual adorned)
+ public static void SetAdornedElement(Visual adorner, Visual? adorned)
{
adorner.SetValue(AdornedElementProperty, adorned);
}