RichTextBox 当前滚动位置
RichTextBox current scroll position
如果是 RichTextBox(行号或 TextPointer
),我希望能够获取当前的垂直滚动位置。
在我的场景中,我有一个反汇编程序,用户选择行和选项以将汇编行重新格式化为字节、单词、文本等。这很好用。它还会导致如此多的更改,以至于 FlowDocument
被重新创建,并且在重新创建文本后默认滚动到顶部。我更改了我的代码,以便它获取当前选择的行号并在文本更改时滚动到该行。问题在于它将行放在顶部。我希望它根本不滚动。我有可以滚动到任何行号的代码,或者它可以从 TextPointer
获取行号并滚动到该行号。如果我可以在更改文本之前获取滚动值,我可以重新滚动到该值,这样文本就不会跳转。
var line = FindLineNumber(ref RichTextListing.RichText, RichTextListing.RichText.Selection.Start);
View.Flow = doc;
ScrollToLine(ref RichTextListing.RichText, line);
private TextPointer GetTextPosition(ref RichTextBox rtb, int line)
{
var p = rtb.Document.ContentStart;
var findStart = p.GetLineStartPosition(0);
if (findStart == null)
{
return p;
}
var lineNum = 0;
while (lineNum < line)
{
findStart = findStart.GetLineStartPosition(1, out _);
lineNum++;
}
return findStart;
}
private int FindLineNumber(ref RichTextBox rtb, TextPointer p)
{
var findStart = p?.GetLineStartPosition(0);
if (findStart == null) return 0;
var startLinePosition = rtb.Document.ContentStart.GetLineStartPosition(0);
if (startLinePosition == null) return 0;
var foundLineNumber = 0;
while (true)
{
if (startLinePosition.CompareTo(findStart) >= 0)
{
break;
}
startLinePosition = startLinePosition.GetLineStartPosition(1, out var result);
if (result == 0)
{
break;
}
foundLineNumber++;
}
return foundLineNumber;
}
private void ScrollToLine(ref RichTextBox rtb, int line)
{
var pos = GetTextPosition(ref rtb, line);
if (pos == null) return;
if (pos.Parent is FrameworkContentElement e)
{
e.BringIntoView();
}
}
考虑以下代码。
定义:
private TextPointer ChangesStartPosition { get; set; }
在文档中进行更改之前设置 ChangesStartPosition
属性:
// `rtb` in the code below is the RichTextBox
ChangesStartPosition = rtb.Selection.IsEmpty ? rtb.CaretPosition : rtb.Selection.Start;
在文档中执行更改后,使用以下代码使插入符号在 RichTextBox
中居中:
var rect = ChangesStartPosition.GetCharacterRect(LogicalDirection.Forward);
rtb.ScrollToVerticalOffset(rtb.VerticalOffset + rect.Top - rtb.ActualHeight / 2d);
rtb.CaretPosition = ChangesStartPosition;
如果ChangesStartPosition
属性引用的文档的一部分发生变化,ChangesStartPosition
失效,那么调用前需要计算一个新的TextPointer
值ScrollToVerticalOffset()
.
如果是 RichTextBox(行号或 TextPointer
),我希望能够获取当前的垂直滚动位置。
在我的场景中,我有一个反汇编程序,用户选择行和选项以将汇编行重新格式化为字节、单词、文本等。这很好用。它还会导致如此多的更改,以至于 FlowDocument
被重新创建,并且在重新创建文本后默认滚动到顶部。我更改了我的代码,以便它获取当前选择的行号并在文本更改时滚动到该行。问题在于它将行放在顶部。我希望它根本不滚动。我有可以滚动到任何行号的代码,或者它可以从 TextPointer
获取行号并滚动到该行号。如果我可以在更改文本之前获取滚动值,我可以重新滚动到该值,这样文本就不会跳转。
var line = FindLineNumber(ref RichTextListing.RichText, RichTextListing.RichText.Selection.Start);
View.Flow = doc;
ScrollToLine(ref RichTextListing.RichText, line);
private TextPointer GetTextPosition(ref RichTextBox rtb, int line)
{
var p = rtb.Document.ContentStart;
var findStart = p.GetLineStartPosition(0);
if (findStart == null)
{
return p;
}
var lineNum = 0;
while (lineNum < line)
{
findStart = findStart.GetLineStartPosition(1, out _);
lineNum++;
}
return findStart;
}
private int FindLineNumber(ref RichTextBox rtb, TextPointer p)
{
var findStart = p?.GetLineStartPosition(0);
if (findStart == null) return 0;
var startLinePosition = rtb.Document.ContentStart.GetLineStartPosition(0);
if (startLinePosition == null) return 0;
var foundLineNumber = 0;
while (true)
{
if (startLinePosition.CompareTo(findStart) >= 0)
{
break;
}
startLinePosition = startLinePosition.GetLineStartPosition(1, out var result);
if (result == 0)
{
break;
}
foundLineNumber++;
}
return foundLineNumber;
}
private void ScrollToLine(ref RichTextBox rtb, int line)
{
var pos = GetTextPosition(ref rtb, line);
if (pos == null) return;
if (pos.Parent is FrameworkContentElement e)
{
e.BringIntoView();
}
}
考虑以下代码。
定义:
private TextPointer ChangesStartPosition { get; set; }
在文档中进行更改之前设置 ChangesStartPosition
属性:
// `rtb` in the code below is the RichTextBox
ChangesStartPosition = rtb.Selection.IsEmpty ? rtb.CaretPosition : rtb.Selection.Start;
在文档中执行更改后,使用以下代码使插入符号在 RichTextBox
中居中:
var rect = ChangesStartPosition.GetCharacterRect(LogicalDirection.Forward);
rtb.ScrollToVerticalOffset(rtb.VerticalOffset + rect.Top - rtb.ActualHeight / 2d);
rtb.CaretPosition = ChangesStartPosition;
如果ChangesStartPosition
属性引用的文档的一部分发生变化,ChangesStartPosition
失效,那么调用前需要计算一个新的TextPointer
值ScrollToVerticalOffset()
.