WPF中的文本度量

WPF中的文本度量,wpf,formatting,Wpf,Formatting,使用WPF,测量大量短字符串的最有效方法是什么?具体来说,我想确定每个字符串的显示高度,给定统一的格式(相同的字体、大小、重量等)和字符串可能占用的最大宽度?您可以在渲染文本框上使用DesiredSize属性来获取高度和宽度 using System.Windows.Threading; ... Double TextWidth = 0; Double TextHeight = 0; ... MyTextBox.Text = "Words to measure size of"; this

使用WPF,测量大量短字符串的最有效方法是什么?具体来说,我想确定每个字符串的显示高度,给定统一的格式(相同的字体、大小、重量等)和字符串可能占用的最大宽度?

您可以在渲染文本框上使用DesiredSize属性来获取高度和宽度

using System.Windows.Threading;

...

Double TextWidth = 0;
Double TextHeight = 0;
...

MyTextBox.Text = "Words to measure size of";
this.Dispatcher.BeginInvoke(
    DispatcherPriority.Background,
    new DispatcherOperationCallback(delegate(Object state) {
        var size = MyTextBox.DesiredSize;
        this.TextWidth = size.Width;
        this.TextHeight = size.Height;
        return null; 
    }
) , null);

如果您有大量的字符串,那么首先预先计算给定字体中每个单独字母和符号的高度和宽度,然后根据字符串字符进行计算可能会更快。由于紧排等原因,这可能不是100%准确率。最低级的技术(因此提供了最大的创造性优化空间)是使用Glyphrun

虽然没有很好的文档记录,但我在这里写了一个小例子:


该示例在呈现字符串之前计算出字符串的长度,这是一个必要的步骤。

非常简单,由FormattedText类完成! 试试看。

在WPF中:

在读取DesiredSize属性之前,请记住对TextBlock调用Measure()

如果TextBlock是动态创建的,但尚未显示,则必须首先调用Measure(),如下所示:

MyTextBlock.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));

return new Size(MyTextBlock.DesiredSize.Width, MyTextBlock.DesiredSize.Height);
在Silverlight中:

不需要测量

return new Size(TextBlock.ActualWidth, TextBlock.ActualHeight);
完整的代码如下所示:

public Size MeasureString(string s) {

    if (string.IsNullOrEmpty(s)) {
        return new Size(0, 0);
    }

    var TextBlock = new TextBlock() {
        Text = s
    };

#if SILVERLIGHT
    return new Size(TextBlock.ActualWidth, TextBlock.ActualHeight);
#else
    TextBlock.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));

    return new Size(TextBlock.DesiredSize.Width, TextBlock.DesiredSize.Height);
#endif
}

MSDN论坛上的同一个问题得到了一些更好的解决方案:FormattedText在UniversalWindows中不可用,请帮助我!丹尼尔,这个例子似乎没有考虑到更复杂的概念,比如字距和标准连字,你能确认一下吗(10年后:)?