WPF C# 获取 TextBlock 的内联元素的大小和位置 [英] WPF C# get the size and position of inline element of a TextBlock

查看:84
本文介绍了WPF C# 获取 TextBlock 的内联元素的大小和位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用这个例子(https://siderite.dev/blog/how-to-draw-outlined-text-in-wpf-and.html ) 用于为 TextBlock 中的文本添加轮廓.但是这个例子不支持内联.

I use this example ( https://siderite.dev/blog/how-to-draw-outlined-text-in-wpf-and.html ) for add outline to a text in a TextBlock. However this example don't support Inlines.

我尝试添加此功能,修改 OnRender 并迭代 Inlines 集合,为每个 Inline 块构建一个 Geometry.问题是我需要获取 TextBlock 中内联块的位置和大小,而不是 TextBlock 中整个文本的位置和大小.

I try to add this ability modifying the OnRender and I iterate the Inlines collection to build a Geometry for each Inline block. The problem is that I need to get the position and size of the inline block in the TextBlock instead of those of the whole text in the TextBlock.

这是我修改过的源代码.

This is the source code that I have modified.

protected override void OnRender(DrawingContext drawingContext)
{
    ensureTextBlock();
    base.OnRender(drawingContext);

    foreach (Inline inline in _textBlock.Inlines)
    {
        var textRange = new TextRange(inline.ContentStart, inline.ContentEnd);
        var formattedText = new FormattedText(
            textRange.Text,
            CultureInfo.CurrentUICulture,
            inline.FlowDirection,
            new Typeface(inline.FontFamily, inline.FontStyle, inline.FontWeight, inline.FontStretch),
            inline.FontSize, System.Windows.Media.Brushes.Black // This brush does not matter since we use the geometry of the text.
        );
        formattedText.SetTextDecorations(inline.TextDecorations);


        //*****************************************************************
        //This part get the size and position of the TextBlock
        // Instead I need to find a way to get the size and position of the Inline block

        //formattedText.TextAlignment = _textBlock.TextAlignment;
        //formattedText.Trimming = _textBlock.TextTrimming;

        formattedText.LineHeight = _textBlock.LineHeight;
        formattedText.MaxTextWidth = _textBlock.ActualWidth - _textBlock.Padding.Left - _textBlock.Padding.Right;
        formattedText.MaxTextHeight = _textBlock.ActualHeight - _textBlock.Padding.Top;// - _textBlock.Padding.Bottom;
        while (formattedText.Extent == double.NegativeInfinity)
        {
            formattedText.MaxTextHeight++;
        }

        // Build the geometry object that represents the text.
        var _textGeometry = formattedText.BuildGeometry(new System.Windows.Point(_textBlock.Padding.Left, _textBlock.Padding.Top));

        //*****************************************************************


        var textPen = new System.Windows.Media.Pen(Stroke, StrokeThickness * 2)
        {
            DashCap = PenLineCap.Round,
            EndLineCap = PenLineCap.Round,
            LineJoin = PenLineJoin.Round,
            StartLineCap = PenLineCap.Round
        };

        var boundsGeo = new RectangleGeometry(new Rect(0, 0, ActualWidth, ActualHeight));

        _clipGeometry = Geometry.Combine(boundsGeo, _textGeometry, GeometryCombineMode.Exclude, null);
        drawingContext.PushClip(_clipGeometry);
        drawingContext.DrawGeometry(System.Windows.Media.Brushes.Transparent, textPen, _textGeometry);
        drawingContext.Pop();
    }
}

我需要更改从 TextBlock 获取大小和位置的部分,以便获取 Inline 块的大小和位置,但是我没有看到任何可以获取该信息的 Inline 属性.有什么想法吗?

I need to change the part that get the size and position from the TextBlock in order to get the size and position of the Inline block, but I don't see any property of Inline that can get that information. Any idea?

推荐答案

我找到了一种获得职位的方法:

I have found a way to get the position with:

inline.ElementStart.GetCharacterRect(LogicalDirection.Forward).Left
inline.ElementStart.GetCharacterRect(LogicalDirection.Forward).Top

然后我以这种方式更改了构建几何图形的线:

Then I changed the line that build the geometry in this way:

double posLeft = inline.ElementStart.GetCharacterRect(LogicalDirection.Forward).Left;
double posTop = inline.ElementStart.GetCharacterRect(LogicalDirection.Forward).Top;

var _textGeometry = formattedText.BuildGeometry(new System.Windows.Point(posLeft, posTop));

我仍然有一些换行问题,因为当文本被换行时,Geometry 仅构建在第一行中.

I still have some problem with wrap because when the text is wrapped the Geometry is built only in the first line.

这篇关于WPF C# 获取 TextBlock 的内联元素的大小和位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆