diff --git a/samples/Sandbox/MainWindow.axaml b/samples/Sandbox/MainWindow.axaml
index 0fc78795a6..cf2ce63c1f 100644
--- a/samples/Sandbox/MainWindow.axaml
+++ b/samples/Sandbox/MainWindow.axaml
@@ -9,6 +9,21 @@
+
+
+
+
+
+
diff --git a/samples/Sandbox/MainWindow.axaml.cs b/samples/Sandbox/MainWindow.axaml.cs
index 7a8b56bbb6..3040385708 100644
--- a/samples/Sandbox/MainWindow.axaml.cs
+++ b/samples/Sandbox/MainWindow.axaml.cs
@@ -3,7 +3,9 @@ using System.Diagnostics;
using System.Runtime.CompilerServices;
using Avalonia;
using Avalonia.Controls;
+using Avalonia.Controls.Documents;
using Avalonia.Controls.Presenters;
+using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Avalonia.VisualTree;
@@ -11,6 +13,8 @@ namespace Sandbox
{
public class MainWindow : Window
{
+ private TestViewModel _dc;
+
public MainWindow()
{
this.InitializeComponent();
@@ -27,13 +31,30 @@ namespace Sandbox
var textPresenter = e.NameScope.Find("PART_TextPresenter") as TextPresenter;
- DataContext = new TestViewModel(textPresenter);
+ _dc = new TestViewModel(textPresenter);
+
+ DataContext = _dc;
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
+
+ private void Button_OnClick(object? sender, RoutedEventArgs e)
+ {
+ _dc.InlineCollection = new InlineCollection
+ {
+ new Run(""),
+ new Run("test3") {FontWeight = Avalonia.Media.FontWeight.Bold},
+ };
+ // _dc.Text = "nununu";
+ }
+
+ private void TextButton_OnClick(object? sender, RoutedEventArgs e)
+ {
+ _dc.Text = "nununu";
+ }
}
public class TestViewModel : ViewModelBase
@@ -46,6 +67,29 @@ namespace Sandbox
_textPresenter = textPresenter;
}
+ private InlineCollection _inlineCollection;
+ private string _text;
+
+ public string Text
+ {
+ get => _text;
+ set
+ {
+ _text = value;
+ RaisePropertyChanged();
+ }
+ }
+
+ public InlineCollection InlineCollection
+ {
+ get => _inlineCollection;
+ set
+ {
+ _inlineCollection = value;
+ RaisePropertyChanged();
+ }
+ }
+
public double Distance
{
get => _distance;
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextLayout.cs b/src/Avalonia.Base/Media/TextFormatting/TextLayout.cs
index f3e8b5969c..0828b6518a 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextLayout.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextLayout.cs
@@ -537,8 +537,13 @@ namespace Avalonia.Media.TextFormatting
///
/// The collapsing width.
/// The .
- private TextCollapsingProperties GetCollapsingProperties(double width)
+ private TextCollapsingProperties? GetCollapsingProperties(double width)
{
+ if(_textTrimming == TextTrimming.None)
+ {
+ return null;
+ }
+
return _textTrimming.CreateCollapsingProperties(new TextCollapsingCreateInfo(width, _paragraphProperties.DefaultTextRunProperties));
}
}
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextLine.cs b/src/Avalonia.Base/Media/TextFormatting/TextLine.cs
index c8a23097db..61b24dc8c5 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextLine.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextLine.cs
@@ -153,7 +153,7 @@ namespace Avalonia.Media.TextFormatting
///
/// A value that represents a collapsed line that can be displayed.
///
- public abstract TextLine Collapse(params TextCollapsingProperties[] collapsingPropertiesList);
+ public abstract TextLine Collapse(params TextCollapsingProperties?[] collapsingPropertiesList);
///
/// Create a justified line based on justification text properties.
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs b/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
index 0ee791d935..a0aae76fad 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
@@ -119,7 +119,7 @@ namespace Avalonia.Media.TextFormatting
}
///
- public override TextLine Collapse(params TextCollapsingProperties[] collapsingPropertiesList)
+ public override TextLine Collapse(params TextCollapsingProperties?[] collapsingPropertiesList)
{
if (collapsingPropertiesList.Length == 0)
{
@@ -128,6 +128,11 @@ namespace Avalonia.Media.TextFormatting
var collapsingProperties = collapsingPropertiesList[0];
+ if(collapsingProperties is null)
+ {
+ return this;
+ }
+
var collapsedRuns = collapsingProperties.Collapse(this);
if (collapsedRuns is null)
diff --git a/src/Avalonia.Controls/RichTextBlock.cs b/src/Avalonia.Controls/RichTextBlock.cs
index 0c8b1d125d..2f8bed3be7 100644
--- a/src/Avalonia.Controls/RichTextBlock.cs
+++ b/src/Avalonia.Controls/RichTextBlock.cs
@@ -44,8 +44,8 @@ namespace Avalonia.Controls
///
/// Defines the property.
///
- public static readonly StyledProperty InlinesProperty =
- AvaloniaProperty.Register(
+ public static readonly StyledProperty InlinesProperty =
+ AvaloniaProperty.Register(
nameof(Inlines));
public static readonly DirectProperty CanCopyProperty =
@@ -138,7 +138,7 @@ namespace Avalonia.Controls
/// Gets or sets the inlines.
///
[Content]
- public InlineCollection Inlines
+ public InlineCollection? Inlines
{
get => GetValue(InlinesProperty);
set => SetValue(InlinesProperty, value);
@@ -159,7 +159,7 @@ namespace Avalonia.Controls
remove => RemoveHandler(CopyingToClipboardEvent, value);
}
- internal bool HasComplexContent => Inlines.Count > 0;
+ internal bool HasComplexContent => Inlines != null && Inlines.Count > 0;
///
/// Copies the current selection to the Clipboard.
@@ -260,18 +260,18 @@ namespace Avalonia.Controls
{
if (!string.IsNullOrEmpty(_text))
{
- Inlines.Add(_text);
+ Inlines?.Add(_text);
_text = null;
}
- Inlines.Add(text);
+ Inlines?.Add(text);
}
}
protected override string? GetText()
{
- return _text ?? Inlines.Text;
+ return _text ?? Inlines?.Text;
}
protected override void SetText(string? text)
@@ -301,10 +301,10 @@ namespace Avalonia.Controls
ITextSource textSource;
- var inlines = Inlines;
-
if (HasComplexContent)
{
+ var inlines = Inlines!;
+
var textRuns = new List();
foreach (var inline in inlines)
@@ -537,7 +537,7 @@ namespace Avalonia.Controls
switch (change.Property.Name)
{
- case nameof(InlinesProperty):
+ case nameof(Inlines):
{
OnInlinesChanged(change.OldValue as InlineCollection, change.NewValue as InlineCollection);
InvalidateTextLayout();
@@ -553,7 +553,7 @@ namespace Avalonia.Controls
return "";
}
- var text = Inlines.Text ?? Text;
+ var text = GetText();
if (string.IsNullOrEmpty(text))
{
diff --git a/tests/Avalonia.Controls.UnitTests/RichTextBlockTests.cs b/tests/Avalonia.Controls.UnitTests/RichTextBlockTests.cs
index eb4b88956d..c74f13b808 100644
--- a/tests/Avalonia.Controls.UnitTests/RichTextBlockTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/RichTextBlockTests.cs
@@ -48,5 +48,49 @@ namespace Avalonia.Controls.UnitTests
Assert.False(target.IsMeasureValid);
}
}
+
+ [Fact]
+ public void Changing_Inlines_Should_Invalidate_Measure()
+ {
+ using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
+ {
+ var target = new RichTextBlock();
+
+ var inlines = new InlineCollection { new Run("Hello") };
+
+ target.Measure(Size.Infinity);
+
+ Assert.True(target.IsMeasureValid);
+
+ target.Inlines = inlines;
+
+ Assert.False(target.IsMeasureValid);
+ }
+ }
+
+ [Fact]
+ public void Changing_Inlines_Should_Reset_Inlines_Parent()
+ {
+ using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
+ {
+ var target = new RichTextBlock();
+
+ var run = new Run("Hello");
+
+ target.Inlines.Add(run);
+
+ target.Measure(Size.Infinity);
+
+ Assert.True(target.IsMeasureValid);
+
+ target.Inlines = null;
+
+ Assert.Null(run.Parent);
+
+ target.Inlines = new InlineCollection { run };
+
+ Assert.Equal(target, run.Parent);
+ }
+ }
}
}
diff --git a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs
index 6d057d900e..c457a96299 100644
--- a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs
+++ b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs
@@ -993,9 +993,11 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
var currentX = 0.0;
- for (int j = 0; j < clusters.Count; j++)
- {
- var cluster = clusters[j];
+ var cluster = text.Length;
+
+ for (int j = 0; j < clusters.Count - 1; j++)
+ {
+ var glyphAdvance = glyphAdvances[j];
var characterHit = textLine.GetCharacterHitFromDistance(currentX);
@@ -1005,9 +1007,9 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
Assert.Equal(currentX, distance);
- var glyphAdvance = glyphAdvances[j];
-
currentX += glyphAdvance;
+
+ cluster = clusters[j];
}
}
}