Browse Source

Handler Adorner property changes

pull/9012/head
Wiesław Šoltés 4 years ago
parent
commit
82aebeeb34
  1. 89
      src/Avalonia.Controls/Primitives/AdornerLayer.cs

89
src/Avalonia.Controls/Primitives/AdornerLayer.cs

@ -36,9 +36,13 @@ namespace Avalonia.Controls.Primitives
private static readonly AttachedProperty<AdornedElementInfo> s_adornedElementInfoProperty =
AvaloniaProperty.RegisterAttached<AdornerLayer, Visual, AdornedElementInfo>("AdornedElementInfo");
private static readonly AttachedProperty<AdornerLayer?> s_savedAdornerLayerProperty =
AvaloniaProperty.RegisterAttached<Visual, Visual, AdornerLayer?>("SavedAdornerLayer");
static AdornerLayer()
{
AdornedElementProperty.Changed.Subscribe(AdornedElementChanged);
AdornerProperty.Changed.Subscribe(AdornerChanged);
}
public AdornerLayer()
@ -79,36 +83,79 @@ namespace Avalonia.Controls.Primitives
public static void SetAdorner(Visual visual, Control? adorner)
{
visual.SetValue(AdornerProperty, adorner);
SetVisualAdorner(visual, adorner);
}
private static void SetVisualAdorner(Visual visual, Control? adorner)
private static void AdornerChanged(AvaloniaPropertyChangedEventArgs<Control?> e)
{
var layer = default(AdornerLayer);
visual.AttachedToVisualTree += (_, _) =>
if (e.Sender is Visual visual)
{
layer = AddVisualAdorner(visual, adorner);
};
var oldAdorner = e.OldValue.GetValueOrDefault();
var newAdorner = e.NewValue.GetValueOrDefault();
if (Equals(oldAdorner, newAdorner))
{
return;
}
if (oldAdorner is { })
{
visual.AttachedToVisualTree -= VisualOnAttachedToVisualTree;
visual.DetachedFromVisualTree -= VisualOnDetachedFromVisualTree;
Detach(visual, oldAdorner);
}
visual.DetachedFromVisualTree += (_, _) =>
if (newAdorner is { })
{
visual.AttachedToVisualTree += VisualOnAttachedToVisualTree;
visual.DetachedFromVisualTree += VisualOnDetachedFromVisualTree;
Attach(visual, newAdorner);
}
}
}
private static void VisualOnAttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
if (sender is Visual visual)
{
RemoveVisualAdorner(visual, adorner, layer);
};
var adorner = GetAdorner(visual);
if (adorner is { })
{
Attach(visual, adorner);
}
}
}
private static AdornerLayer? AddVisualAdorner(Visual visual, Control? adorner)
private static void VisualOnDetachedFromVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
if (adorner is null)
if (sender is Visual visual)
{
return null;
var adorner = GetAdorner(visual);
if (adorner is { })
{
Detach(visual, adorner);
}
}
}
private static void Attach(Visual visual, Control adorner)
{
var layer = AdornerLayer.GetAdornerLayer(visual);
if (layer == null || layer.Children.Contains(adorner))
AddVisualAdorner(visual, adorner, layer);
visual.SetValue(s_savedAdornerLayerProperty, layer);
}
private static void Detach(Visual visual, Control adorner)
{
var layer = visual.GetValue(s_savedAdornerLayerProperty);
RemoveVisualAdorner(visual, adorner, layer);
visual.ClearValue(s_savedAdornerLayerProperty);
}
private static void AddVisualAdorner(Visual visual, Control? adorner, AdornerLayer? layer)
{
if (adorner is null || layer == null || layer.Children.Contains(adorner))
{
return layer;
return;
}
AdornerLayer.SetAdornedElement(adorner, visual);
@ -116,19 +163,11 @@ namespace Avalonia.Controls.Primitives
((ISetLogicalParent) adorner).SetParent(visual);
layer.Children.Add(adorner);
return layer;
}
private static void RemoveVisualAdorner(Visual visual, Control? adorner, AdornerLayer? layer)
{
if (adorner is null)
{
return;
}
// var layer = AdornerLayer.GetAdornerLayer(visual);
if (layer is null || !layer.Children.Contains(adorner))
if (adorner is null || layer is null || !layer.Children.Contains(adorner))
{
return;
}

Loading…
Cancel
Save