c# - WPF C#获取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));
我仍然对换行有一些问题,因为当文本被换行时,几何仅在第一行中构建。
推荐阅读
- html - 如何以角度解析嵌套的json
- java - 客户端无法使用自签名证书连接到 REST API
- rust - 如何通过 curl 使用 actix-from-data 的映射数组发出 POST 请求?
- asp.net - 如何用我在 iis 服务器上运行的 asp.net 中的自定义值替换缓存控制安全标头值中的私有值
- jquery - jQuery - 有多个总计的总计
- sprite-kit - 如何使用 SpriteKit 在圆上通过给定偏移创建点?
- c# - 以 xamarin 形式将对象放置在 TabbedPage 上的绝对位置
- python - 将列表的字典转换为字典中列表中元素的所有梳的字典列表的最pythonic方法?
- xcode - 无法初始化可可豆荚
- python-3.x - 将数字限制为特定的小数位