gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 09:11:16 25 4
gpt4 key购买 nike

假设我有 2 个 TextPointer。一个指向单词的开头,另一个指向单词的结尾。

我想在单词周围绘制单像素边框。我该怎么做?边框应该与单词相关联,并在用户键入或滚动时随之移动。

我已经用 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. 装饰者应该 Hook 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));
    }

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

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

关于c# - 如何在 RichTextBox 中的单词周围绘制边框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6158291/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com