0

RichTextBox.PageWidth のサイズを 1 行あたり 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 に答える