Browse Source

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
pull/3119/head
Steven Kirk 7 years ago
parent
commit
d1ad46d07e
  1. 15
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

15
src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

@ -148,6 +148,19 @@ namespace Avalonia.Rendering.SceneGraph
return (VisualNode)node; 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) private static void Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, bool forceRecurse)
{ {
var visual = node.Visual; var visual = node.Visual;
@ -231,7 +244,7 @@ namespace Avalonia.Rendering.SceneGraph
{ {
foreach (var child in visual.VisualChildren.OrderBy(x => x, ZIndexComparer.Instance)) 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); Update(context, scene, (VisualNode)childNode, clip, forceRecurse);
} }

Loading…
Cancel
Save