el_*_*yan 7 wpf inline effects decorator custom-controls
有没有办法创建一个在其内容上绘制对角线的自定义FrameworkContentElement
(或Inline
)?
像穿透装饰但具有对角线形状的东西:
它不可能是固有的(TextDecoration
或TextEffect
它们是密封的).
任何的想法?
更新:
我尝试尽可能少地创建一个示例.在更复杂的场景中,您必须扩展它.以下是它的外观:
这是相应的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>
Run Code Online (Sandbox Code Playgroud)
这就是代码隐藏:
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));
}));
}
Run Code Online (Sandbox Code Playgroud)
玩得开心!
原始讯息:
这通常很难.我已经设法将一个装饰器附加到flowdocuments中的特定元素,但有许多角落要考虑.例如:如果Inline缠绕在一起会发生什么?进一步说:如果这个flowdocument位于richtextbox中,它的内部保持重新排列运行(连接或分离它们),这几乎弄乱了所有东西.你必须仔细设置.
请详细说明此内联的位置.在FlowdocumentScrollviewer中?还是一个TextBlock?还是Richtextbox?因为您必须将装饰器附加到管理FrameworkElement(因为您可能已经注意到您无法直接将装饰器附加到FrameworkContentElement),我们需要知道内联所在的位置.
我将描述如何实现这一目标的一般途径:创建一个附加属性,用于创建装饰器.附加属性设置在将要装饰的内联中.adorner保留对内联的引用,并附加到管理FrameworkElement.subscibe to layoutupdated on frameworkelement并在Adorner上执行InvalidateVisual.装饰者OnRender根据Inlines ContentStart和ContentEnd GetCharacterRect矩形绘制具有坐标的线.完成.
归档时间: |
|
查看次数: |
1338 次 |
最近记录: |