簡體   English   中英

WPF C# 獲取 TextBlock 的內聯元素的大小和位置

[英]WPF C# get the size and position of inline element of a TextBlock

我使用此示例( https://siderite.dev/blog/how-to-draw-outlined-text-in-wpf-and.html )為 TextBlock 中的文本添加輪廓。 但是這個例子不支持內聯。

我嘗試添加這種修改 OnRender 的能力,並迭代 Inlines 集合來為每個 Inline 塊構建一個 Geometry。 問題是我需要獲取 TextBlock 中內聯塊的位置和大小,而不是 TextBlock 中整個文本的位置和大小。

這是我修改過的源代碼。

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 屬性。 任何的想法?

我找到了一種獲得職位的方法:

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

然后我以這種方式更改了構建幾何圖形的線:

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

我仍然有一些換行的問題,因為當文本被換行時,幾何只構建在第一行。

嘗試這個

Rect rect = Rect.Union(inline.ElementStart.GetCharacterRect(LogicalDirection.Forward),                                                
                       inline.ElementEnd.GetCharacterRect(LogicalDirection.Backward));

謝謝

使用 TextBlock 的 LineHeight 屬性:

formattedText.LineHeight = _textBlock.LineHeight;

因此,您可以通過編程方式修改 LineHeight 值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM