Open gebodal opened 3 months ago
OK, I realised there's a simple enough hack for this, where you just have to replace the TextEditor.ShowLineNumbers
setter logic with your own. The only important point is that you have to wait until the control is loaded before disabling, otherwise the EmSize
will not have been set correctly.
The below uses a modified version of the TextEditor
code here:
https://github.com/AvaloniaUI/AvaloniaEdit/blob/f92e5527c0f6ef1a1a6f6d2dc904af5688315949/src/AvaloniaEdit/TextEditor.cs#L549-L560
public MyControl() {
// Other initialisation here
//// Line numbers setup
// Set to true initially so that internal values get initialised properly
textEditor.ShowLineNumbers = true;
// Collect list of line controls (following logic in TextEditor.cs#L549-L560)
List<Control> lineNumberControlsList = new List<Control>();
var leftMargins = textEditor.TextArea.LeftMargins;
for (int i = 0; i < leftMargins.Count; i++) {
if (leftMargins[i] is LineNumberMargin) {
lineNumberControlsList.Add(leftMargins[i]);
if (i + 1 < leftMargins.Count && DottedLineMargin.IsDottedLineMargin(leftMargins[i + 1])) {
lineNumberControlsList.Add(leftMargins[i + 1]);
}
break;
}
}
lineNumberControls = lineNumberControlsList.ToArray();
// When finished loading, set visibility to desired value
textEditor.Loaded += OnLoadedAdjustShowLineNumbers;
}
private readonly Control[] lineNumberControls;
// Adjust the visibility of the line number controls without actually removing them
public bool ShowLineNumbers {
get {
return lineNumberControls.Any(c => c.IsVisible); // Or something neater
}
set {
foreach(Control c in lineNumberControls) {
c.IsVisible = value;
}
}
}
private void OnLoadedAdjustShowLineNumbers(object? sender, RoutedEventArgs e) {
ShowLineNumbers = MyDataManager.GetShowLineNumbers();
}
Or something like that, anyway. (Seems to work on my machine!)
Unless I'm missing something, it seems that changing the
ShowLineNumbers
property of a loadedTextEditor
fromfalse
totrue
will cause anArgumentOutOfRangeException
that seems to be originating fromLineNumberMargin.Render()
. Specifically, this error is occurring in aTextEditor
hosted inside aWindow
which has finished loading and is visible, with theShowLineNumbers
property being changed via user interaction.https://github.com/AvaloniaUI/AvaloniaEdit/blob/f92e5527c0f6ef1a1a6f6d2dc904af5688315949/src/AvaloniaEdit/Editing/LineNumberMargin.cs#L76-L80
It seems that the
EmSize
(taken from theTextBlock.FontSizeProperty
) is not being set somehow, possibly because it is set inMeasureOverride()
, which presumably is not being called before rendering?https://github.com/AvaloniaUI/AvaloniaEdit/blob/f92e5527c0f6ef1a1a6f6d2dc904af5688315949/src/AvaloniaEdit/Editing/LineNumberMargin.cs#L55
The "OnChanged" method for
ShowLineNumbers
inTextEditor
creates a brand newLineNumberMargin
Control
when set totrue
fromfalse
, so even if altered in sequencetrue
->false
->true
, the error occurs.Stack trace of error:
If there's a workaround, I'd love to hear about it! So far I have tried:
InvalidateMeasure()
,InvalidateArrange()
andInvalidateVisual()
after changingShowLineNumbers
on theTextEditor
, theTextArea
, and allControl
s intextArea.LeftMargins
; usingDispatcher.UIThread.Invoke()
to change the value ofShowLineNumbers
. None of these have solved the issue.