ОБНОВЛЕНИЕ :
Я попытался создать пример как можно меньше.В более сложных сценариях вам придется расширить это.Вот как это выглядит:
это соответствующий xaml:
<AdornerDecorator>
<StackPanel>
<TextBlock>
<Run>this is normal Text</Run><LineBreak/>
<Run local:DiagonalStrikeThroughAdorner.StrikeThroughBrush="Red">Some text with diagonal decoration</Run><LineBreak/>
<Run>more normal text yeah</Run>
</TextBlock>
<FlowDocumentScrollViewer>
<FlowDocument>
<Paragraph>
<Run>this is normal Text</Run>
<LineBreak/>
<Run local:DiagonalStrikeThroughAdorner.StrikeThroughBrush="Red">Some text with diagonal decoration</Run>
<LineBreak/>
<Run>more normal text yeah</Run>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
</StackPanel>
</AdornerDecorator>
, и это код:
public class DiagonalStrikeThroughAdorner : Adorner
{
private readonly Inline _inline;
private readonly Pen _pen;
public DiagonalStrikeThroughAdorner(UIElement adornedElement, Inline inline, Brush brush) : base(adornedElement)
{
_inline = inline;
_pen = new Pen(brush, 2);
}
protected override void OnRender(DrawingContext drawingContext)
{
if(!(_inline.ContentStart.HasValidLayout && _inline.ContentEnd.HasValidLayout))
return;
var startrect = _inline.ContentStart.GetCharacterRect(LogicalDirection.Forward);
var endrect = _inline.ContentEnd.GetCharacterRect(LogicalDirection.Backward);
drawingContext.DrawLine(_pen,startrect.BottomLeft,endrect.TopRight);
}
public static Brush GetStrikeThroughBrush(DependencyObject obj)
{
return (Brush)obj.GetValue(StrikeThroughBrushProperty);
}
public static void SetStrikeThroughBrush(DependencyObject obj, Brush value)
{
obj.SetValue(StrikeThroughBrushProperty, value);
}
public static readonly DependencyProperty StrikeThroughBrushProperty =
DependencyProperty.RegisterAttached("StrikeThroughBrush", typeof(Brush), typeof(DiagonalStrikeThroughAdorner), new UIPropertyMetadata((o, args) =>
{
if(!(o is TextElement)) return;
var parent = ((TextElement)o).Parent;
while (parent is FrameworkContentElement)
parent = ((FrameworkContentElement) parent).Parent;
if (parent == null || !(parent is Visual)) return;
var adornerLayer = AdornerLayer.GetAdornerLayer((Visual) parent);
if(adornerLayer == null) return;
adornerLayer.Add(new DiagonalStrikeThroughAdorner((UIElement) parent,o as Inline,(Brush) args.NewValue));
}));
}
весело провести время!
оригинальное сообщение :
это обычно довольно сложно.Мне удалось прикрепить рекламное объявление к конкретным элементам в flowdocuments, но есть много угловых случаев для рассмотрения.например: что должно произойти, если этот Inline обернут?далее: если этот потоковый документ находится в текстовом поле richtextbox, его внутренние компоненты продолжают перестраивать прогоны (объединяя или разделяя их), что в значительной степени портит все.Вы должны тщательно все настроить.
Пожалуйста, опишите подробнее, где будет находиться эта строка.Внутри FlowdocumentScrollviewer?Или текстовый блок?Или Richtextbox?Так как вам нужно прикрепить рекламодателя к управляющему FrameworkElement (как вы, вероятно, уже заметили, вы не можете напрямую прикрепить рекламодатель к FrameworkContentElement), нам нужно знать, где находится встроенный элемент.
Я опишу общий маршруто том, как этого добиться: создайте прикрепленное свойство, которое будет создавать рекламодатель.прикрепленное свойство устанавливается на встроенном, который будет украшен.владелец сохраняет ссылку на встроенный элемент и присоединяется к управляющему элементу FrameworkElement.подпишитесь на макет, обновленный на этом элементе кадра, и сделайте визуальный недействительный на Adorner.Украшающие OnRender рисуют линию с координатами в зависимости от прямоугольников Inlines ContentStart и ContentEnd GetCharacterRect .сделано.