diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs
index 458e972db3..1c60c0d906 100644
--- a/src/Avalonia.Controls/Presenters/TextPresenter.cs
+++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs
@@ -78,14 +78,14 @@ namespace Avalonia.Controls.Presenters
private int _selectionEnd;
private bool _caretBlink;
private string _text;
- private TextLayout _textLayout;
+ private TextLayout? _textLayout;
private Size _constraint = Size.Infinity;
private CharacterHit _lastCharacterHit;
private Rect _caretBounds;
private Point _navigationPosition;
- private ScrollViewer _scrollViewer;
+ private ScrollViewer? _scrollViewer;
static TextPresenter()
{
@@ -99,7 +99,7 @@ namespace Avalonia.Controls.Presenters
_caretTimer.Tick += CaretTimerTick;
}
- public event EventHandler CaretBoundsChanged;
+ public event EventHandler? CaretBoundsChanged;
///
/// Gets or sets a brush used to paint the control's background.
@@ -186,7 +186,7 @@ namespace Avalonia.Controls.Presenters
///
/// Gets the used to render the text.
///
- public TextLayout TextLayout
+ public TextLayout? TextLayout
{
get
{
@@ -284,13 +284,20 @@ namespace Avalonia.Controls.Presenters
///
///
/// A object.
- private TextLayout CreateTextLayoutInternal(Size constraint, string text, Typeface typeface,
- IReadOnlyList> textStyleOverrides)
+ private TextLayout? CreateTextLayoutInternal(Size constraint, string text, Typeface typeface,
+ IReadOnlyList>? textStyleOverrides)
{
+ var foreground = Foreground;
+
+ if (foreground == null)
+ {
+ return null;
+ }
+
var maxWidth = MathUtilities.IsZero(constraint.Width) ? double.PositiveInfinity : constraint.Width;
var maxHeight = MathUtilities.IsZero(constraint.Height) ? double.PositiveInfinity : constraint.Height;
- var textLayout = new TextLayout(text ?? string.Empty, typeface, FontSize, Foreground, TextAlignment,
+ var textLayout = new TextLayout(text ?? string.Empty, typeface, FontSize, foreground, TextAlignment,
TextWrapping, maxWidth: maxWidth, maxHeight: maxHeight, textStyleOverrides: textStyleOverrides,
flowDirection: FlowDirection);
@@ -310,6 +317,11 @@ namespace Avalonia.Controls.Presenters
context.FillRectangle(background, new Rect(Bounds.Size));
}
+ if (TextLayout == null)
+ {
+ return;
+ }
+
var top = 0d;
var left = 0.0;
@@ -344,7 +356,7 @@ namespace Avalonia.Controls.Presenters
var selectionStart = SelectionStart;
var selectionEnd = SelectionEnd;
- if (selectionStart != selectionEnd)
+ if (selectionStart != selectionEnd && TextLayout != null)
{
var start = Math.Min(selectionStart, selectionEnd);
var length = Math.Max(selectionStart, selectionEnd) - start;
@@ -458,9 +470,9 @@ namespace Avalonia.Controls.Presenters
/// Creates the used to render the text.
///
/// A object.
- protected virtual TextLayout CreateTextLayout()
+ protected virtual TextLayout? CreateTextLayout()
{
- TextLayout result;
+ TextLayout? result;
var text = Text;
@@ -471,7 +483,7 @@ namespace Avalonia.Controls.Presenters
var start = Math.Min(selectionStart, selectionEnd);
var length = Math.Max(selectionStart, selectionEnd) - start;
- IReadOnlyList> textStyleOverrides = null;
+ IReadOnlyList>? textStyleOverrides = null;
if (length > 0)
{
@@ -512,7 +524,7 @@ namespace Avalonia.Controls.Presenters
InvalidateTextLayout();
}
- return TextLayout.Size;
+ return TextLayout?.Size ?? default;
}
private int CoerceCaretIndex(int value)
@@ -522,7 +534,7 @@ namespace Avalonia.Controls.Presenters
return Math.Max(0, Math.Min(length, value));
}
- private void CaretTimerTick(object sender, EventArgs e)
+ private void CaretTimerTick(object? sender, EventArgs e)
{
_caretBlink = !_caretBlink;
InvalidateVisual();
@@ -530,6 +542,11 @@ namespace Avalonia.Controls.Presenters
public void MoveCaretToTextPosition(int textPosition, bool trailingEdge = false)
{
+ if (TextLayout == null)
+ {
+ return;
+ }
+
var lineIndex = TextLayout.GetLineIndexFromCharacterIndex(textPosition, trailingEdge);
var textLine = TextLayout.TextLines[lineIndex];
@@ -556,6 +573,11 @@ namespace Avalonia.Controls.Presenters
public void MoveCaretToPoint(Point point)
{
+ if (TextLayout == null)
+ {
+ return;
+ }
+
var hit = TextLayout.HitTestPoint(point);
UpdateCaret(hit.CharacterHit);
@@ -565,6 +587,11 @@ namespace Avalonia.Controls.Presenters
public void MoveCaretVertical(LogicalDirection direction = LogicalDirection.Forward)
{
+ if (TextLayout == null)
+ {
+ return;
+ }
+
var lineIndex = TextLayout.GetLineIndexFromCharacterIndex(CaretIndex, _lastCharacterHit.TrailingLength > 0);
if (lineIndex < 0)
@@ -606,6 +633,11 @@ namespace Avalonia.Controls.Presenters
public void MoveCaretHorizontal(LogicalDirection direction = LogicalDirection.Forward)
{
+ if (TextLayout == null)
+ {
+ return;
+ }
+
var characterHit = _lastCharacterHit;
var caretIndex = characterHit.FirstCharacterIndex + characterHit.TrailingLength;
@@ -681,6 +713,11 @@ namespace Avalonia.Controls.Presenters
private void UpdateCaret(CharacterHit characterHit)
{
+ if (TextLayout == null)
+ {
+ return;
+ }
+
_lastCharacterHit = characterHit;
var caretIndex = characterHit.FirstCharacterIndex + characterHit.TrailingLength;
diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs
index 274074030a..dc6b8ffa4c 100644
--- a/src/Avalonia.Controls/TextBox.cs
+++ b/src/Avalonia.Controls/TextBox.cs
@@ -937,7 +937,7 @@ namespace Avalonia.Controls
{
selection = DetectSelection();
- _presenter?.MoveCaretVertical();
+ _presenter.MoveCaretVertical();
if (caretIndex != _presenter.CaretIndex)
{
@@ -1273,7 +1273,7 @@ namespace Avalonia.Controls
{
caretIndex = 0;
}
- else
+ else if (_presenter.TextLayout is not null)
{
var lines = _presenter.TextLayout.TextLines;
var pos = 0;
@@ -1308,7 +1308,7 @@ namespace Avalonia.Controls
{
caretIndex = text.Length;
}
- else
+ else if (_presenter.TextLayout is not null)
{
var lines = _presenter.TextLayout.TextLines;
var pos = 0;