0

我正在尝试将我的 RichTextBox.PageWidth 的大小限制为每行 60 个字符(固定宽度字体)。基本上我测量字符串,然后将 PageWidth 设置为测量的量。

当我使用它时,我的测量值相差 2 个字符。(最后 2 个字符换行到下一行。)

任何人都知道如何获取我的 RichTextBox 的字符串宽度,而无需实际将该文本放入 RichTextBox

字符串测量方法(取自此处):

private static double GetStringWidth(string text, 
                                     FontFamily fontFamily, 
                                     double fontSize)
{
    Typeface typeface = new Typeface(fontFamily, 
                                     FontStyles.Normal, 
                                     FontWeights.Normal, 
                                     FontStretches.Normal);

    GlyphTypeface glyphTypeface;
    if (!typeface.TryGetGlyphTypeface(out glyphTypeface))
        throw new InvalidOperationException("No glyph typeface found");

    double size = fontSize;

    ushort[] glyphIndexes = new ushort[text.Length];
    double[] advanceWidths = new double[text.Length];

    double totalWidth = 0;

    for (int n = 0; n < text.Length; n++)
    {
        ushort glyphIndex = glyphTypeface.CharacterToGlyphMap[text[n]];
        glyphIndexes[n] = glyphIndex;

        double width = glyphTypeface.AdvanceWidths[glyphIndex] * size;
        advanceWidths[n] = width;

        totalWidth += width;
    }

    return totalWidth;
}

使用上述方法:

var strToMeasure="012345678901234567890123456789012345678901234567890123456789";
richTextBox.FontFamily = new FontFamily("Courier New");
var fontFamily = richTextBox.FontFamily;
var fontSize = richTextBox.FontSize;

var measuredWidth = GetStringWidth(strToMeasure, fontFamily, fontSize);

richTextBox.Document.PageWidth = measuredWidth;
richTextBox.Document.MaxPageWidth = measuredWidth;
richTextBox.Document.MinPageWidth = measuredWidth;

更新:
进一步的测试表明它一直关闭 2 个字符(4 个字符或 100 个字符)。这让我相信 RichTextBox 正在填充一些东西。

4

2 回答 2

2

RichTextBox 可能会出于自己的布局目的而消耗其一些水平宽度,从而导致您的计算总是有点短。这个 stackOverflow 问题的答案应该可以帮助您解决问题。

根据等宽字体的大小设置 WPF RichTextBox 的宽度和高度

于 2012-12-13T23:17:32.057 回答
1

我使用这种方法,它可能不是最好的,但它非常准确。

    private double MeasureText(string text, FontFamily font, double fontsize)
    {
        var mesureLabel = new TextBlock(); 
        mesureLabel.FontFamily = font;
        mesureLabel.FontSize = fontsize; 
        mesureLabel.Text = text; 
        mesureLabel.Padding = new Thickness(0); 
        mesureLabel.Margin = new Thickness(0); 
        mesureLabel.Width = double.NaN; 
        mesureLabel.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 
        mesureLabel.Arrange(new Rect(mesureLabel.DesiredSize));
        return mesureLabel.ActualWidth;
    }

用法:

 double length = MeasureText("hello", FontFamily, FontSize);
于 2012-12-13T23:32:29.513 回答