diff --git a/src/Avalonia.Controls/Documents/InlineCollection.cs b/src/Avalonia.Controls/Documents/InlineCollection.cs
index dc6f828234..f3d32d92d3 100644
--- a/src/Avalonia.Controls/Documents/InlineCollection.cs
+++ b/src/Avalonia.Controls/Documents/InlineCollection.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Avalonia.Collections;
using Avalonia.LogicalTree;
using Avalonia.Metadata;
@@ -23,32 +24,8 @@ namespace Avalonia.Controls.Documents
ResetBehavior = ResetBehavior.Remove;
this.ForEachItem(
- x =>
- {
- x.InlineHost = InlineHost;
-
- LogicalChildren?.Add(x);
-
- if (x is InlineUIContainer container)
- {
- InlineHost?.VisualChildren.Add(container.Child);
- }
-
- Invalidate();
- },
- x =>
- {
- LogicalChildren?.Remove(x);
-
- if(x is InlineUIContainer container)
- {
- InlineHost?.VisualChildren.Remove(container.Child);
- }
-
- x.InlineHost = null;
-
- Invalidate();
- },
+ OnAdd,
+ OnRemove,
() => throw new NotSupportedException());
}
@@ -70,9 +47,11 @@ namespace Avalonia.Controls.Documents
get => _inlineHost;
set
{
+ var oldValue = _inlineHost;
+
_inlineHost = value;
- OnInlineHostChanged(value);
+ OnInlineHostChanged(oldValue, value);
}
}
@@ -118,7 +97,7 @@ namespace Avalonia.Controls.Documents
///
/// Adds a text segment to the collection.
///
- /// For non complex content this appends the text to the end of currently held text.
+ /// For non-complex content this appends the text to the end of currently held text.
/// For complex content this adds a to the collection.
///
///
@@ -159,25 +138,66 @@ namespace Avalonia.Controls.Documents
Invalidated?.Invoke(this, EventArgs.Empty);
}
- private void OnParentChanged(IAvaloniaList? oldParent, IAvaloniaList? newParent)
+ private void OnParentChanged(ICollection? oldValue, ICollection? newValue)
{
foreach (var child in this)
{
- if (oldParent != newParent)
+ if (Equals(oldValue, newValue))
{
- oldParent?.Remove(child);
-
- newParent?.Add(child);
+ continue;
}
+
+ oldValue?.Remove(child);
+
+ newValue?.Add(child);
}
+
+ Invalidate();
}
- private void OnInlineHostChanged(IInlineHost? inlineHost)
+ private void OnInlineHostChanged(IInlineHost? oldValue, IInlineHost? newValue)
{
foreach (var child in this)
{
- child.InlineHost = inlineHost;
+ if (child is not InlineUIContainer container)
+ {
+ continue;
+ }
+
+ oldValue?.VisualChildren.Remove(container.Child);
+
+ newValue?.VisualChildren.Add(container.Child);
+ }
+
+ Invalidate();
+ }
+
+ private void OnAdd(TextElement inline)
+ {
+ inline.InlineHost = InlineHost;
+
+ LogicalChildren?.Add(inline);
+
+ if (inline is InlineUIContainer container)
+ {
+ InlineHost?.VisualChildren.Add(container.Child);
}
+
+ Invalidate();
+ }
+
+ private void OnRemove(TextElement inline)
+ {
+ LogicalChildren?.Remove(inline);
+
+ if (inline is InlineUIContainer container)
+ {
+ InlineHost?.VisualChildren.Remove(container.Child);
+ }
+
+ inline.InlineHost = null;
+
+ Invalidate();
}
}
}
diff --git a/tests/Avalonia.Controls.UnitTests/TextBlockTests.cs b/tests/Avalonia.Controls.UnitTests/TextBlockTests.cs
index 79a6706983..4e1379c5c2 100644
--- a/tests/Avalonia.Controls.UnitTests/TextBlockTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/TextBlockTests.cs
@@ -51,6 +51,25 @@ namespace Avalonia.Controls.UnitTests
}
}
+ [Fact]
+ public void Changing_Inlines_Should_Attach_Embedded_Controls_To_Parents()
+ {
+ using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
+ {
+ var target = new TextBlock();
+
+ var control = new Border();
+
+ var inlineUIContainer = new InlineUIContainer { Child = control };
+
+ target.Inlines = new InlineCollection { inlineUIContainer };
+
+ Assert.Equal(inlineUIContainer, control.Parent);
+
+ Assert.Equal(target, control.VisualParent);
+ }
+ }
+
[Fact]
public void Can_Call_Measure_Without_InvalidateTextLayout()
{