[英]WPF RichTextBox position caret to visible character with given index
我一直在 WPF 中尋找一種快速方法來以編程方式將光標設置為指定的可見符號索引。
問題是,僅僅通過使用Document.ContentStart.GetPositionAtOffset(cursorIndex, LogicalDirection.Forward)
我沒有得到想要的結果,因為這個方法也計算不可見的符號 - 例如Run
開始和Run
結束符號。 文檔中幾乎總是有一些分界符號,所以這總是以光標位於所需位置之前結束。
那么,僅通過可見符號將插入符定位到指定索引的快速、簡單和優雅的方法是什么?
我想出了以下解決方案:
public virtual void SetCursorIndex(Int32 cursorIndex)
{
// If the specified index is less than or equal to 0, then we simply
// position the caret to the start of the document.
if (cursorIndex <= 0)
{
CaretPosition = Document.ContentStart;
return;
}
// If the specified index is greater than or equal to the total length, we simply
// position the caret to the end of the document.
String fullText = new TextRange(Document.ContentStart, Document.ContentEnd).Text;
Int32 totalTextLength = fullText.Length;
if (cursorIndex >= totalTextLength)
{
CaretPosition = Document.ContentEnd;
return;
}
// (*)
TextPointer endPtr = Document.ContentStart
.GetPositionAtOffset(cursorIndex, LogicalDirection.Forward);
TextRange range = new TextRange(Document.ContentStart, endPtr);
Int32 diff = cursorIndex - range.Text.Length;
while (diff != 0)
{
endPtr = endPtr.GetPositionAtOffset(diff, LogicalDirection.Forward);
range = new TextRange(Document.ContentStart, endPtr);
diff = cursorIndex - range.Text.Length;
// Overindexing, in this case we went over the document's length so we
// position the caret to the end of the document as a safety measure.
if (diff < 0)
{
endPtr = Document.ContentEnd;
break;
}
}
CaretPosition = endPtr;
}
// (*)
之前的部分是不言自明的。 從那里,我們執行以下操作:
cursorIndex
邏輯位置(相對於文檔的開頭)獲取文本指針 - 同樣,這包括不可見的符號。 但是如果是這樣,我們不能超過所需的可見字符索引,只能在它之前。 如果它不包含任何不可見的符號,則此方法為我們提供了一個TextPointer
我們想要的位置的TextPointer
。TextRange
對象,它以文檔開頭和TextPointer
創建的TextPointer
為界。TextRange
對象中計算cursorIndex
和文本Length
的差值。 這是我們迭代推進指針直到差異為 0 的量。這是一個簡單的啟發式方法,比迭代推進它快一點點。它基於這樣一個事實,如果TextRange
對象包含任何不可見的符號,則顯示的符號的數量永遠不會比位置,我們必須推進我們的數量更大endPtr
TextPointer
所以我們做的只是這-我們提前endPtr
通過的差異cursorIndex
和range.Length
。 如果在所需位置和endPtr
指向的當前位置之間有任何不可見的符號,那么我們仍然不會完全到達所需位置 - 這就是為什么我們在while
endPtr
測試中對endPtr
進行推進,以測試長度的差異range
和cursorIndex
包含的文本為 0。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.