Frage

Ich versuche, die Pixelbreite von Excel-Spalten zu berechnen, wie in dieser Beitrag , die offizielle Formel aus der OpenXML-Spezifikation verwenden. Um jedoch diese Formel anzuwenden, muß ich die Maximale Ziffernbreite des Normal Schrift kennen, die die Pixelbreite der breitesten numerischen Ziffer ist. Die OpenXML-Spezifikation gibt dieses Beispiel als Klarstellung:

Verwenden des Calibri Schrift als Beispiel die maximale Ziffernbreite von 11-Punkt-Schrift Größe ist 7 Pixel (bei 96 dpi).

Ich habe überprüft, dass dies durch optisch korrekt ist eine Calibri 11-Punkte-Ziffer zu prüfen und es ist in der Tat 7 Pixel breit. Also, ich versuche, ein Verfahren zu schaffen, das die maximale Ziffernbreite für jede Schriftart / Größe angezeigt werden kann.

Ich habe die Empfehlungen in , aber es produziert nicht die Ergebnisse ich erwarte.

Hier ist mein Test-Code:

var font = new Font("Calibri", 11.0f, FontStyle.Regular);

for (var i = 0; i < 10; i++)
{
    Debug.WriteLine(TextRenderer.MeasureText(i.ToString(), font));
}

Dieser berichtet, dass alle Ziffern eine Breite von 15 haben.

Irgendwelche Vorschläge bitte?

Danke, Tim

War es hilfreich?

Lösung

Lassen Sie mich zuerst sagen, dass der Code, den ich über bin aussieht wie eine schreckliche Hack zu zeigen, und ich präsentieren es nicht als Lösung. Vielmehr Ich hoffe, es ist ein wenig mehr über das Verhalten von measureText zeigt, dass Sie Ihre endgültige Lösung führen könnten.

Ich habe eine leichte Veränderung an Ihrem Code. Ich messe die Länge von zwei Unterstrichen. Dann wird in dem Körper der for-Schleife ich Messen der gewünschten Zeichen mit Unterstreichungen auf beiden Seiten und Subtrahieren der Länge der beiden Unterstreichungszeichen allein. Für das Testszenario ein Ergebnis von 7. Der Hauptzweck dieser erhalte ich war zu bestimmen, ob measureText auf einem Zeichen-für-Zeichen-Basis oder Polsterung am Anfang / Ende der Zeichenfolge für Polsterung ist Buchhaltung. Es scheint, dass es das letztere ist. Vielleicht ist dies mit einigen anderen Eingang kombiniert die Sie erhalten haben, werden Sie auf eine elegantere Lösung führen.

var font = new Font("Calibri", 11.0f, FontStyle.Regular);
int underscoreWidth = TextRenderer.MeasureText("__", font).Width; 
for (var i = 0; i < 10; i++)
   {
      int charWidth = TextRenderer.MeasureText(String.Concat("_", i.ToString(), "_"), font).Width - underscoreWidth;
      Debug.WriteLine(charWidth);
   }

Andere Tipps

TextRenderer- ist nicht immer genau so, wie man es erwarten würde:

Von MSDN: http://msdn.microsoft.com/en- us / library / 8wafk2kt.aspx

  

Zum Beispiel kann das Standardverhalten des TextRenderer- ist Polsterung an das umschließende Rechteck des gezeichneten Text hinzufügen überhängenden Glyphen aufnehmen

Haben Sie ein Graphics Objekt oder ein Control-Objekt haben? Wenn Sie diese verwenden, können Sie genau restults die Art und Weise erhalten Sie erwarten würden.

Hier finden Sie aktuelle http: // msdn. microsoft.com/en-us/library/6xe5hazb(VS.80).aspx

measureText fügt Polsterung, die Menge ziemlich unberechenbar ist, obwohl es in etwa linear mit der Schriftgröße skaliert. Der Trick ist, zwei Messungen subtrahieren der Polsterung loszuwerden. Dieser Code erzeugt sehr glücklich Zahlen:

        float size = 5;
        for (int ix = 0; ix < 10; ++ix) {
            var font = new Font("Calibri", size, FontStyle.Regular);
            string txt = new string('0', 100);
            SizeF sz1 = TextRenderer.MeasureText("00", font) - TextRenderer.MeasureText("0", font);
            Console.WriteLine("{0} {1:N3}", size, sz1.Width);
            size += 2;
        }

Ausgabe:

5 4.000
7 5.000
9 6.000
11 7.000
13 9.000
15 10.000
17 12.000
19 13.000
21 14.000
23 16.000

Das bringt Ihnen die 7 Pixel Sie suchen. Beachten Sie, dass Sie Truetype-Hinting aufnehmen müssen werden, ist es die Form der Ziffer einstellen kann, so dass sein Haupt fällt auf Pixelgrenzen Stielen. Fügen Sie mindestens ein Pixel.

Messtextbreiten kann ein Alptraum sein .. Ich weiß nicht, warum sie es so verwirrend gemacht ..

Heres die genaueste Methode Ive erhielt die Länge des Textes zu messen:

    protected int _MeasureDisplayStringWidth ( Graphics graphics, string text, Font font )
    {
        if ( text == "" )
            return 0;

        StringFormat format = new StringFormat ( StringFormat.GenericDefault );
        RectangleF rect = new RectangleF ( 0, 0, 1000, 1000 );
        CharacterRange[] ranges = { new CharacterRange ( 0, text.Length ) };
        Region[] regions = new Region[1];

        format.SetMeasurableCharacterRanges ( ranges );
        format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;

        regions = graphics.MeasureCharacterRanges ( text, font, rect, format );
        rect = regions[0].GetBounds ( graphics );

        return (int)( rect.Right );
    }

Ich bin nicht 100% sicher, dass es ist, was Sie genau brauchen.

Sie können aber einen Blick auf dieser Microsoft-Seite haben wollen:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top