如何绘制边界周围的RichTextBox一个字? [英] How to draw border around a word in RichTextBox?

查看:137
本文介绍了如何绘制边界周围的RichTextBox一个字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有2 TextPointers。在单词的开头和另一个在单词的末尾一个指向。

Let's say I have 2 TextPointers. One pointing at the beginning of a word and the other at the end of the word.

我想提请围绕这个词单个像素边框。我会如何呢?边框应该连接到这个词,并用它当移动用户类型或滚动..

I would like to draw single pixel border around the word. How would I go about this? The border should be tied to the word and move with it when user types or scrolls..

我已经尝试过用DrawingBrush TextDecorations但未能拿出任何东西使用。

I already tried TextDecorations with DrawingBrush but couldn't come up with anything usable.

推荐答案

我做了什么,在TextBox只强调文本。校长似乎是大致相同。

I have done something similar, only underlining text in a TextBox. The principal seems to be mostly the same.


  1. 添加AdornerDecorator包含您的RichTextBox不过的ScrollViewer内。

  1. Add an AdornerDecorator containing your RichTextBox but inside a ScrollViewer.

<Border ...>
    <ScrollViewer ... >
        <AdornerDecorator>
            <RichTextBox
                x:Name="superMagic"
                HorizontalScrollBarVisibility="Hidden"
                VerticalScrollBarVisibility="Hidden"
                BorderBrush="{x:Null}"
                BorderThickness="0"
                ...
                />
        </AdornerDecorator>
    </ScrollViewer>
</Border>


  • 创建装饰器来呈现矩形,并把它添加到AdornerLayer

  • Create an Adorner to render the rectangle and add it to the AdornerLayer

    void HostControl_Loaded(object sender, RoutedEventArgs e)
    {
        _adorner = new RectangleAdorner(superMagic);
    
        AdornerLayer layer = AdornerLayer.GetAdornerLayer(superMagic);
        layer.Add(_adorner);
    }
    


  • 装饰器勾应在RichTextBox的TextChanged事件。所有你需要做的就是调用 InvalidateVisuals()通过使用 DispatcherPriority.Background 调度,以确保它后呈现文本框。我不知道这是否是一个问题的RichTextBox ,但得到的字符从文本框是唯一可能的坐标如果已经呈现至少一次,因为它的内容最后修改

  • The adorner should hook the TextChanged event of the RichTextBox. All you need to do is call InvalidateVisuals() via the dispatcher using DispatcherPriority.Background to ensure it is rendered after the text box. I don't know if it's an issue for the RichTextBox, but getting the character coordinates from a TextBox is only possible if it has been rendered at least once since it's content last changed.

    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);
        }
    
        // ...
    }
    


  • <李>

    覆盖 Adorner.OnRender()使用绘制盒 TextPointer.GetCharacterRect()来获得。坐标

  • Override Adorner.OnRender() to draw the box using TextPointer.GetCharacterRect() to get the coordinates.

    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));
    }
    


  • 注意虽然最初的代码工作很好,我在很久以前写的,并没有测试过我adaptions了这个答案。它至少应该有助于让你在正确的道路上。

    Note: Although the original code worked well, I wrote it a long time ago and have not tested my adaptions for this answer. It should at least help put you on the right path.

    此外,这不处理那里的字拆分为多行的情况下,但不应该太难满足。

    Also, this does not handle cases where the word is split across lines, but shouldn't be too hard to cater for.

    这篇关于如何绘制边界周围的RichTextBox一个字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆