如何在UWP应用中测量文本大小?

18

在WPF中,可以使用FormattedText来实现此功能,如下所示:

private Size MeasureString(string candidate)
{
    var formattedText = new FormattedText(
        candidate,
        CultureInfo.CurrentUICulture,
        FlowDirection.LeftToRight,
        new Typeface(this.textBlock.FontFamily, this.textBlock.FontStyle, this.textBlock.FontWeight, this.textBlock.FontStretch),
        this.textBlock.FontSize,
        Brushes.Black);

    return new Size(formattedText.Width, formattedText.Height);
}

但是在UWP中这个类已经不存在了。那么在通用Windows平台上如何计算文本大小呢?

3个回答

40
在UWP中,您需要创建一个TextBlock,设置其属性(如TextFontSize),然后调用其Measure方法并传入无限大小。
var tb = new TextBlock { Text = "Text", FontSize = 10 };
tb.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));

在那之后,DesiredSize 属性将包含 TextBlock 的大小。

5
@Reddy 我并不那么快(尽管我希望我能更快)。在提问时有一个“回答你自己的问题”的复选框。我这样做是因为我在SO上没有找到与此问题相关的任何问题或答案,所以其他人可以(希望如此)找到它而不必花费数小时进行搜索。 - Domysee
5
请注意,这并不是特定于UWP的。它同样适用于WPF或Silverlight。 - Clemens
@MarcelW 不太清楚你的意思。对我来说很好用,也适用于WPF。 - Clemens
1
这个运行速度很慢,而且必须在UI线程上运行。有没有人能找到一个可以在后台线程上运行的替代方案? - Paymon
@Paymon:也许这个答案可以帮到你。 - testing
显示剩余2条评论

7

这里提供一种使用Win2D的替代方法:

private Size MeasureTextSize(string text, CanvasTextFormat textFormat, float limitedToWidth = 0.0f, float limitedToHeight = 0.0f)
{
    var device = CanvasDevice.GetSharedDevice();

    var layout = new CanvasTextLayout(device, text, textFormat, limitedToWidth, limitedToHeight);

    var width = layout.DrawBounds.Width;
    var height = layout.DrawBounds.Height;

    return new Size(width, height);
}

你可以这样使用它:
string text = "Lorem ipsum dolor sit amet";

CanvasTextFormat textFormat = new CanvasTextFormat
{
    FontSize = 16,
    WordWrapping = CanvasWordWrapping.WholeWord,
};

Size textSize = this.MeasureTextSize(text, textFormat, 320.0f);

Source


1
这非常棒!但是在某些情况下会给出奇怪的结果:请查看我在此处发布的问题https://stackoverflow.com/questions/55801411/uwp-compute-text-height-in-a-richtextblock-gives-weird-results - Cristiano Ghersi
@CristianoGhersi:如果这是一个文本缩进的问题,那么你可以使用固定值作为解决方法吗?否则我认为你需要使用另一个解决方案... - testing
一个固定值可能完全可以正常工作,你能否再详细阐述一下这个想法?例如,你打算将固定值放在哪里? - Cristiano Ghersi
我想到的方法是通过在字符串开头添加额外的尾随空格来“伪造”缩进。但是,对于将缩进= 10pt转换为我必须添加到字符串中以计算正确的finalH的空格数量的好函数仍然不清楚。 - Cristiano Ghersi
1
使用layout.LayoutBounds代替layout.DrawBoundsLayoutBounds将会给你期望的结果。 - Mohit Atray
显示剩余2条评论

1
如果您在UWP上遇到Size无法解析或与double的使用不正常的问题,那么很可能是因为您正在使用System.Drawing.Size。请改用Windows.Foundation.Size

这是原始回答中的主要遗漏。在C#答案中完全合格化您的类型或添加using语句非常重要。 - wildbagel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接