Browse Source

Fix TextBlock inlines logical tree handling

Benedikt Stebner 3 years ago
parent
commit
9403a3d0c7

+ 13 - 12
src/Avalonia.Controls/Documents/InlineCollection.cs

@@ -12,7 +12,7 @@ namespace Avalonia.Controls.Documents
     [WhitespaceSignificantCollection]
     public class InlineCollection : AvaloniaList<Inline>
     {
-        private ILogical? _parent;
+        private IAvaloniaList<ILogical>? _parent;
         private IInlineHost? _inlineHost;
 
         /// <summary>
@@ -24,28 +24,28 @@ namespace Avalonia.Controls.Documents
 
             this.ForEachItem(
                 x =>
-                {
-                    ((ISetLogicalParent)x).SetParent(Parent);
+                {                   
                     x.InlineHost = InlineHost;
+                    Parent?.Add(x);
                     Invalidate();
                 },
                 x =>
                 {
-                    ((ISetLogicalParent)x).SetParent(null);
+                    Parent?.Remove(x);
                     x.InlineHost = InlineHost;
                     Invalidate();
                 },
                 () => throw new NotSupportedException());
         }
 
-        internal ILogical? Parent
+        internal IAvaloniaList<ILogical>? Parent
         {
             get => _parent;
             set
             {
                 _parent = value;
 
-                OnParentChanged(value);
+                OnParentChanged(_parent, value);
             }
         }
 
@@ -157,20 +157,21 @@ namespace Avalonia.Controls.Documents
             Invalidated?.Invoke(this, EventArgs.Empty);
         }
 
-        private void OnParentChanged(ILogical? parent)
+        private void OnParentChanged(IAvaloniaList<ILogical>? oldParent, IAvaloniaList<ILogical>? newParent)
         {
             foreach (var child in this)
             {
-                var oldParent = child.Parent;
-
-                if (oldParent != parent)
+                if (oldParent != newParent)
                 {
                     if (oldParent != null)
                     {
-                        ((ISetLogicalParent)child).SetParent(null);
+                        oldParent.Remove(child);
                     }
 
-                    ((ISetLogicalParent)child).SetParent(parent);
+                    if(newParent != null)
+                    {
+                        newParent.Add(child);
+                    }
                 }
             }
         }

+ 2 - 2
src/Avalonia.Controls/Documents/Span.cs

@@ -21,7 +21,7 @@ namespace Avalonia.Controls.Documents
         {
             Inlines = new InlineCollection
             {
-                Parent = this
+                Parent = LogicalChildren
             };
         }
 
@@ -85,7 +85,7 @@ namespace Avalonia.Controls.Documents
 
             if (newValue is not null)
             {
-                newValue.Parent = this;
+                newValue.Parent = LogicalChildren;
                 newValue.InlineHost = InlineHost;
                 newValue.Invalidated += (s, e) => InlineHost?.Invalidate();
             }

+ 12 - 5
src/Avalonia.Controls/TextBlock.cs

@@ -156,7 +156,7 @@ namespace Avalonia.Controls
         {
             Inlines = new InlineCollection
             {
-                Parent = this,
+                Parent = LogicalChildren,
                 InlineHost = this
             };
         }
@@ -635,9 +635,16 @@ namespace Avalonia.Controls
             {
                 if (_textRuns != null)
                 {
-                    LogicalChildren.Clear();
+                    foreach (var textRun in _textRuns)
+                    {
+                        if (textRun is EmbeddedControlRun controlRun &&
+                            controlRun.Control is Control control)
+                        {
+                            VisualChildren.Remove(control);
 
-                    VisualChildren.Clear();
+                            LogicalChildren.Remove(control);
+                        }
+                    }
                 }
 
                 var textRuns = new List<TextRun>();
@@ -772,7 +779,7 @@ namespace Avalonia.Controls
 
             if (newValue is not null)
             {
-                newValue.Parent = this;
+                newValue.Parent = LogicalChildren;
                 newValue.InlineHost = this;
                 newValue.Invalidated += (s, e) => InvalidateTextLayout();
             }
@@ -841,7 +848,7 @@ namespace Avalonia.Controls
                         continue;
                     }
 
-                    if (textRun is TextCharacters textCharacters)
+                    if (textRun is TextCharacters)
                     {
                         return new TextCharacters(textRun.Text.Skip(Math.Max(0, textSourceIndex - currentPosition)), textRun.Properties!);
                     }