繁体   English   中英

如何在 RichTextBox 中的单词周围绘制边框?

[英]How to draw border around a word in RichTextBox?

假设我有 2 个 TextPointers。 一个指向词首,另一个指向词尾。

我想在单词周围绘制单个像素边框。 我将如何 go 关于这个? 当用户键入或滚动时,边框应与单词绑定并随之移动。

我已经用 DrawingBrush 尝试了 TextDecorations,但没有想出任何可用的东西。

我做了类似的事情,只是在 TextBox 中为文本加下划线。 校长似乎大多相同。

  1. 添加包含 RichTextBox 但在 ScrollViewer 内的 AdornerDecorator。

     <Border...> <ScrollViewer... > <AdornerDecorator> <RichTextBox x:Name="superMagic" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" BorderBrush="{x:Null}" BorderThickness="0"... /> </AdornerDecorator> </ScrollViewer> </Border>
  2. 创建一个 Adorner 来渲染矩形并将其添加到 AdornerLayer

     void HostControl_Loaded(object sender, RoutedEventArgs e) { _adorner = new RectangleAdorner(superMagic); AdornerLayer layer = AdornerLayer.GetAdornerLayer(superMagic); layer.Add(_adorner); }
  3. 装饰器应挂钩 RichTextBox 的 TextChanged 事件。 您需要做的就是使用DispatcherPriority.Background通过调度程序调用InvalidateVisuals()以确保它在文本框之后呈现。 我不知道这是否是RichTextBox的问题,但只有在自上次更改内容后至少呈现一次时,才能从TextBox获取字符坐标。

     class RectangleAdorner: Adorner { public RectangleAdorner(RichTextBox textbox): base(textbox) { textbox.TextChanged += delegate { SignalInvalidate(); }; } void SignalInvalidate() { RichTextBox box = (RichTextBox)this.AdornedElement; box.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)InvalidateVisual); } //... }
  4. 覆盖Adorner.OnRender()以使用TextPointer.GetCharacterRect()绘制框以获取坐标。

     protected override void OnRender(DrawingContext drawingContext) { TextPointer start; TextPointer end; // Find the start and end of your word // Actually, if you did this in the TextChanged event handler, // you could probably save some calculation time on large texts // by considering what actually changed relative to an earlier // calculation. (TextChangedEventArgs includes a list of changes // - 'n' characters inserted here, 'm' characters deleted there). Rect startRect = start.GetCharacterRect(LogicalDirection.Backward); Rect endRect = end.GetCharacterRect(LogicalDirection.Forward); drawingContext.DrawRectangle(null, pen, Rect.Union(startRect, endRect)); }

注意:虽然原始代码运行良好,但我很久以前就写过了,还没有测试我对这个答案的改编。 它至少应该帮助你走上正确的道路。

此外,这不处理单词跨行拆分的情况,但不应该太难满足。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM