诀窍是让您覆盖 RichTextBox 的面板(我猜它是 Canvas?)实际存在于富文本所在的同一 ScrollViewer 中。
以下是非常粗略的想法,但应该可以帮助您找到合理的解决方案。
您可以使用RichTextBox 的自定义样式来执行此操作。这个控件的默认样式可以在here找到。
将此样式复制到包含 UserControl 的资源中,并将 RichTextBox Style 属性指向它。到目前为止,没有什么不同,但现在您可以使用该模板。相关部分目前如下所示:-
<Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent">
<ScrollViewer x:Name="ContentElement" Padding="{TemplateBinding Padding}" BorderThickness="0" IsTabStop="False" />
</Border>
现在我们可以这样调整它:-
<Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent">
<ScrollViewer Padding="{TemplateBinding Padding}" BorderThickness="0" IsTabStop="False">
<Grid>
<ContentControl x:Name="ContentElement" />
<Canvas x:Name="HighlightOverlay" />
</Grid>
</ScrollViewer>
</Border>
您会注意到,我们已将名称“ContentElement”从ScrollViewer 移至新的ContentControl。拥有一个名为“ContentElement”的FrameworkElement 是 RichTextBox 对其模板规定的唯一功能。
现在覆盖这个ContentControl,我们可以放置一个Canvas,您可以在其中放置突出显示的矩形。如果用户滚动此RichTextBox,则包含内容和亮点的整个Grid 将一起滚动。
剩下的唯一技巧是获取“HighlightOverlay”,以便您可以将矩形添加到其中。这是一些可以抓取它的代码:-
private Canvas HightlightOverlay;
public MyUserControl()
{
InitializeComponent();
MyRichText.LayoutUpdated += MyRichText_LayoutUpdated;
}
void MyRichText_LayoutUpdated(object sender, EventArgs e)
{
HightlightOverlay = MyRichText.Descendents()
.OfType<Canvas>()
.FirstOrDefault(elem => elem.Name == "HighlightOverlay");
}
你会想知道Descendents方法是从哪里来的,它是here。