После установки текста моего RichTextBox в строку T позиция каретки в RichTextBox «теряется» (она идет в начало). Вот что я делаю, чтобы попытаться «восстановить» его после того, как он «потерян»:

public static int GetCaretIndex(RichTextBox C)
{
    return new TextRange(C.Document.ContentStart, C.CaretPosition).Text.Length;
}
...
int CaretIndex = GetCaretIndex(C); // Get the Caret position before setting the text of the RichTextBox
new TextRange(C.Document.ContentStart, C.Document.ContentEnd).Text = T; // Set the text of the RichTextBox
C.CaretPosition = C.Document.ContentStart.GetPositionAtOffset(CaretIndex, LogicalDirection.Forward); // Set the Caret Position based on the "Caret Index" variable

Этот код, однако, не работает. «Восстановленная» карета находится в другом положении, чем «оригинальная» (по какой-то причине она всегда отстает от «оригинальной»).

«Сохранение» CaretPosition RichTextBox как TextPointer, похоже, тоже не работает.

Может ли кто-нибудь предоставить мне альтернативный способ «восстановления» Карета или способ исправления кода выше?

4
Polygons 29 Май 2017 в 00:08

2 ответа

Лучший ответ

Кажется, работает (для меня): < Код > C.CaretPosition = C.Document.ContentStart; C.CaretPosition = C.CaretPosition.GetPositionAtOffset (CaretIndex, LogicalDirection.Forward);

(Кстати, я ненавижу RichTextBox.)

3
Maciek Świszczowski 28 Май 2017 в 21:51

Недавно я имел дело с подобной проблемой, и у меня есть решение. В моем случае я создаю новый контент RichTextBox.Document, и когда я делаю это, я хочу сохранить позицию каретки.

Моя идея заключалась в том, что функции смещения каретки смещены благодаря структурам данных, используемым для представления текста (Paragraphs, Runs, ...), которые также каким-то образом рассчитываются для смещения позиции.

TextRange - это хороший подход для точного определения положения каретки в тексте. Проблема заключается в его восстановлении. Но становится легко, когда я знаю, из каких компонентов построен мой документ. В моем случае есть только параграфы и прогоны.

Осталось только просмотреть структуру документа, найти точный прогон, где должна быть каретка, и установить каретку, чтобы исправить положение найденного прогона.

Код:

// backup caret position in text
int backPosition = 
    new TextRange(RichTextBox.CaretPosition.DocumentStart, RichTextBox.CaretPosition).Text.Length;

// set new content (caret position is lost there)
RichTextBox.Document.Blocks.Clear();
SetNewDocumentContent(RichTextBox.Document);

// find position and run to which place caret
int pos = 0; Run caretRun = null;
foreach (var block in RichTextBox.Document.Blocks)
{
    if (!(block is Paragraph para))
        continue;

    foreach (var inline in para.Inlines){
    {
        if (!(inline is Run run))
            continue;

        // find run to which place caret
        if (caretRun == null && backPosition > 0)
        {
            pos += run.Text.Length;
            if (pos >= backPosition){
                 caretRun = run;
                 break;
            }
        }
    }

    if (caretRun!=null)
        break;
}

// restore caret position
if (caretRun != null)
    RichTextBox.CaretPosition = 
        caretRun.ContentEnd.GetPositionAtOffset(backPosition - pos, LogicalDirection.Forward);

Код не проверен. Я собрал его из разных частей моего приложения. Дайте мне знать, если найдете какие-либо проблемы.

4
Dave 16 Май 2018 в 17:11