比方說,我有2個TextPointers。一個指向一個詞的開頭,另一個指向詞尾。如何在RichTextBox中圍繞單詞繪製邊框?
我想在單詞的周圍繪製單個像素邊框。我會怎麼做呢?當用戶鍵入或滾動時,應將邊框綁定到該單詞上並隨其移動。
我已經使用DrawingBrush嘗試過TextDecorations,但無法提供任何可用的東西。
比方說,我有2個TextPointers。一個指向一個詞的開頭,另一個指向詞尾。如何在RichTextBox中圍繞單詞繪製邊框?
我想在單詞的周圍繪製單個像素邊框。我會怎麼做呢?當用戶鍵入或滾動時,應將邊框綁定到該單詞上並隨其移動。
我已經使用DrawingBrush嘗試過TextDecorations,但無法提供任何可用的東西。
我做了類似的事情,只在文本框中加下劃線。校長似乎大部分是一樣的。
添加包含您的RichTextBox的AdornerDecorator但裏面的ScrollViewer。
<Border ...>
<ScrollViewer ... >
<AdornerDecorator>
<RichTextBox
x:Name="superMagic"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
BorderBrush="{x:Null}"
BorderThickness="0"
...
/>
</AdornerDecorator>
</ScrollViewer>
</Border>
創建一個裝飾器來呈現矩形,並把它添加到AdornerLayer
void HostControl_Loaded(object sender, RoutedEventArgs e)
{
_adorner = new RectangleAdorner(superMagic);
AdornerLayer layer = AdornerLayer.GetAdornerLayer(superMagic);
layer.Add(_adorner);
}
裝飾器應該勾在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);
}
// ...
}
覆蓋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));
}
注:儘管最初的代碼工作很好,我很久以前寫的,並沒有測試我adaptions了這個答案。它至少應該幫助你走上正確的道路。
而且,這種不處理,其中字拆分爲多行的情況,但不應該太難應付。
好我會測試這個。 – Kugel 2011-05-28 19:36:11
完美的作品! :) – JanDotNet 2017-01-06 13:26:05