2011-05-27 18 views
9

Diyelim ki 2 TextPointer'ım var. Biri kelimenin başlangıcında bir sözcüğün diğerini işaret eder.RichTextBox'ta bir kelimenin etrafındaki kenarlık nasıl çizilir?

Kelimenin etrafında tek piksel kenarlık çizmek istiyorum. Bunun için nasıl giderim? Kenarlık, kullanıcı türüne veya kaydırmaya başladığında bu kelimeye bağlı kalmalı ve onunla birlikte hareket etmelidir ..

DrawingBrush ile TextDecorations kullanmayı denedim, ancak kullanılabilir bir şeyle karşılaşmadım.

cevap

7

Benzer bir şey yaptım, yalnızca bir TextBox'ta metnin altını çiziyorum. Müdür çoğunlukla aynı görünüyor.

  1. RichTextBox'unuzu içeren ancak bir ScrollViewer'ın içinde bir AdornerDecorator ekleyin.

    <Border ...> 
        <ScrollViewer ... > 
         <AdornerDecorator> 
          <RichTextBox 
           x:Name="superMagic" 
           HorizontalScrollBarVisibility="Hidden" 
           VerticalScrollBarVisibility="Hidden" 
           BorderBrush="{x:Null}" 
           BorderThickness="0" 
           ... 
           /> 
         </AdornerDecorator> 
        </ScrollViewer> 
    </Border> 
    
  2. dikdörtgen hale ve RichTextBox'un TextChanged olay bağlamalı

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

    eklemek için bir Adorner oluşturun. Yapmanız gereken tek şey, metin kutusundan sonra işlendiğinden emin olmak için InvalidateVisuals()'u DispatcherPriority.Background kullanarak dağıtıcı aracılığıyla arayabilmektir. RichTextBox için bir sorun olup olmadığını bilmiyorum, ancak TextBox karakter koordinatlarını almak, yalnızca içeriği en son değiştirildiği için en az bir kez oluşturulduysa mümkündür.

    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. geçersiz kılma Adorner.OnRender() koordinatlarını almak için TextPointer.GetCharacterRect() kullanarak kutu çizmek için.

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

Not: Orijinal kod iyi çalıştı rağmen, uzun zaman önce yazdım ve bu yanıt için benim uyarlamalar test etmedim. En azından sizi doğru yola koymaya yardım etmeli. Ayrıca, bu durum satırların satırlar arasında dağıldığı durumları işlemez, ancak bunları karşılamak için çok zor olmamalıdır. Üste |

+0

Harika bunu test edeceğim. – Kugel

+0

Mükemmel çalışıyor! :) – JanDotNet

İlgili konular