gpt4 book ai didi

wpf - 创建自定义 FrameworkContentElement 以在 WPF 中的文本上添加对角线

转载 作者:行者123 更新时间:2023-12-04 11:59:59 24 4
gpt4 key购买 nike

有没有办法创建自定义FrameworkContentElement (或 Inline )在其内容上画一条对角线?

类似于删除线装饰但具有对角线形状的东西:
example of strike-through and diagonal decorations

不可能来自 TextDecorationTextEffect (它们是密封的)。

任何的想法?

最佳答案

更新 :

我试图创建一个尽可能少的例子。在更复杂的场景中,您将不得不扩展它。这是它的外观:

enter image description here

这是相应的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 被环绕会发生什么?进一步:如果这个流程文档位于一个富文本框中,它的内部结构会不断重新排列运行(加入或分离它们),这几乎会把一切搞砸。你必须仔细设置。

请详细说明此内联的位置。在 FlowdocumentScrollviewer 里面?还是文本块?还是富文本框?由于您必须将装饰器附加到管理的 FrameworkElement(正如您可能已经注意到的那样,您不能将装饰器直接附加到 FrameworkContentElement)我们需要知道内联所在的位置。

不过,我将描述如何实现这一点的一般路线:创建一个将要创建装饰器的附加属性。附加属性设置在将要装饰的内联上。装饰器保留对内联的引用并附加到管理框架元素。订阅该框架元素上的 layoutupdated 并在 Adorner 上执行 InvalidateVisual。装饰器 OnRender 根据内联 ContentStart 绘制带有坐标的线和内容结束 GetCharacterRect矩形。完毕。

关于wpf - 创建自定义 FrameworkContentElement 以在 WPF 中的文本上添加对角线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5432395/

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