WPF RichTextBox:查找当前在 RichTextBox 中可见的第一个 block/paragraph
WPF RichTextBox: Find the first block/paragraph that is currently visible in the RichTextBox
情况
我有一个 95% 的工作应用程序(WPF 应用程序/.Net 4.8)执行以下操作:
- 左边一个WPF RichTextBox
- 在右侧一个 WebBrowser 控件
- 左侧:用户在 RichTextBox 中写入 MarkDown 文本
- 右侧:用户实时看到HTML文本
目标
- 当用户滚动 RichTextBox(左侧)时,左侧第一个可见的 block/paragraph 也应该是右侧第一个可见的 block/paragraph。
问题
- 无法通过同步 ScrollViewer 来达到目标。 (FontSizes/Styles 相差太大)
- 目标可以,但不应该通过使用 RichTextBox.CaretPosition(MouseClick => CaretPosition => GetTextUnderCaret => ScrollHTML => 用户不够友好)
- System.Windows.Documents.Block class 不是 FrameworkElement。这意味着,我可以 NOT 这样做:
string text = null;
foreach (var block in RichTextBox.Document.Blocks)
{
//This does not work. Block is not a FrameworkElement...shit...
var blockIsVisible = IsUserVisible(block, RichTextBox);
if (blockIsVisible)
{
var text = new TextRange(block.ContentStart, block.ContentEnd).Text;
break;
}
}
if (!string.IsNullOrWhiteSpace(text))
{
//Scroll to given text in HTML with JQuery...
}
private bool IsUserVisible(FrameworkElement element, FrameworkElement container)
{
if (!element.IsVisible) return false;
Rect bounds = element.TransformToAncestor(container).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
Rect rect = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight);
return rect.Contains(bounds.TopLeft) || rect.Contains(bounds.BottomRight);
}
最后是我的问题
如何确定 WPF RichTextBox 中第一个 visible 行/block/paragraph?
此代码获取第一个可见段落(不一定是第一个可见行!)
TextPointer tp = richTextBox.GetPositionFromPoint(new Point(0, 0), true);
FirstParagraphLine = ((Run)tp.Paragraph.Inlines.FirstInline).Text;
情况
我有一个 95% 的工作应用程序(WPF 应用程序/.Net 4.8)执行以下操作:
- 左边一个WPF RichTextBox
- 在右侧一个 WebBrowser 控件
- 左侧:用户在 RichTextBox 中写入 MarkDown 文本
- 右侧:用户实时看到HTML文本
目标
- 当用户滚动 RichTextBox(左侧)时,左侧第一个可见的 block/paragraph 也应该是右侧第一个可见的 block/paragraph。
问题
- 无法通过同步 ScrollViewer 来达到目标。 (FontSizes/Styles 相差太大)
- 目标可以,但不应该通过使用 RichTextBox.CaretPosition(MouseClick => CaretPosition => GetTextUnderCaret => ScrollHTML => 用户不够友好)
- System.Windows.Documents.Block class 不是 FrameworkElement。这意味着,我可以 NOT 这样做:
string text = null;
foreach (var block in RichTextBox.Document.Blocks)
{
//This does not work. Block is not a FrameworkElement...shit...
var blockIsVisible = IsUserVisible(block, RichTextBox);
if (blockIsVisible)
{
var text = new TextRange(block.ContentStart, block.ContentEnd).Text;
break;
}
}
if (!string.IsNullOrWhiteSpace(text))
{
//Scroll to given text in HTML with JQuery...
}
private bool IsUserVisible(FrameworkElement element, FrameworkElement container)
{
if (!element.IsVisible) return false;
Rect bounds = element.TransformToAncestor(container).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
Rect rect = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight);
return rect.Contains(bounds.TopLeft) || rect.Contains(bounds.BottomRight);
}
最后是我的问题
如何确定 WPF RichTextBox 中第一个 visible 行/block/paragraph?
此代码获取第一个可见段落(不一定是第一个可见行!)
TextPointer tp = richTextBox.GetPositionFromPoint(new Point(0, 0), true);
FirstParagraphLine = ((Run)tp.Paragraph.Inlines.FirstInline).Text;