From d1ad46d07ed6ef6a96d7eaa8b9360d9196a2b833 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 16 Oct 2019 13:23:23 +0200 Subject: [PATCH] Ensure child node has correct parent. When updating the scene, if a control has been reparented then a new `VisualNode` needs to be created to prevent #3095. Check that an existing node has the correct parent and if it doesn't, deindex it and create a new node. Fixes #3095 --- .../Rendering/SceneGraph/SceneBuilder.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs index 87c9ed0bae..558e96e132 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs @@ -148,6 +148,19 @@ namespace Avalonia.Rendering.SceneGraph return (VisualNode)node; } + private static object GetOrCreateChildNode(Scene scene, IVisual child, VisualNode parent) + { + var result = (VisualNode)scene.FindNode(child); + + if (result != null && result.Parent != parent) + { + Deindex(scene, result); + result = null; + } + + return result ?? CreateNode(scene, child, parent); + } + private static void Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, bool forceRecurse) { var visual = node.Visual; @@ -231,7 +244,7 @@ namespace Avalonia.Rendering.SceneGraph { foreach (var child in visual.VisualChildren.OrderBy(x => x, ZIndexComparer.Instance)) { - var childNode = scene.FindNode(child) ?? CreateNode(scene, child, node); + var childNode = GetOrCreateChildNode(scene, child, node); Update(context, scene, (VisualNode)childNode, clip, forceRecurse); }