Skip to content

Commit

Permalink
Fix InlinesCollection Logical/VisualParent update (#14679)
Browse files Browse the repository at this point in the history
* Add failing test

* Update Visual/LogicalTree when parents change
#Conflicts:
#	src/Avalonia.Controls/Documents/InlineCollection.cs
  • Loading branch information
Gillibald authored and maxkatz6 committed Feb 22, 2024
1 parent 833af16 commit 2d89813
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 41 deletions.
96 changes: 55 additions & 41 deletions src/Avalonia.Controls/Documents/InlineCollection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Avalonia.Collections;
using Avalonia.LogicalTree;
using Avalonia.Metadata;
Expand All @@ -23,32 +24,8 @@ public InlineCollection()
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());
}

Expand All @@ -70,9 +47,11 @@ public InlineCollection()
get => _inlineHost;
set
{
var oldValue = _inlineHost;

_inlineHost = value;

OnInlineHostChanged(value);
OnInlineHostChanged(oldValue, value);
}
}

Expand Down Expand Up @@ -118,7 +97,7 @@ public override void Add(Inline inline)
/// <summary>
/// Adds a text segment to the collection.
/// <remarks>
/// 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 <see cref="Run"/> to the collection.
/// </remarks>
/// </summary>
Expand Down Expand Up @@ -162,31 +141,66 @@ protected void Invalidate()
Invalidated?.Invoke(this, EventArgs.Empty);
}

private void OnParentChanged(IAvaloniaList<ILogical>? oldParent, IAvaloniaList<ILogical>? newParent)
private void OnParentChanged(ICollection<ILogical>? oldValue, ICollection<ILogical>? newValue)
{
foreach (var child in this)
{
if (oldParent != newParent)
if (Equals(oldValue, newValue))
{
if (oldParent != null)
{
oldParent.Remove(child);
}

if (newParent != null)
{
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();
}
}
}
19 changes: 19 additions & 0 deletions tests/Avalonia.Controls.UnitTests/TextBlockTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,25 @@ public void Changing_InlinesCollection_Should_Invalidate_Measure()
}
}

[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()
{
Expand Down

0 comments on commit 2d89813

Please sign in to comment.