DrawString-Größe



  • Hallo

    kann man eigentlich die Größe eines mit Draw-String gezeichneten Zeichenkette ermitteln? Ich möchte nämlich genau dahinter eine weitere Zeichenkette zeichnen. Dazu benötige die Koordinaten vom ersten String - genauer gesagt: Die Koordianten, an welchen der String aufhört.

    Danke und Gruß

    Kramny



  • Such mal nach einer MeasureString-Methode vom Graphics Objekt.



  • Danke, genau das habe ich gesucht und nicht gewusst wo ich suchen muss.



  • Eigentlich ganz einfach, z.B. in der Behandlung des Paint-Event:

    void MyPaint(object sender, PaintEventArgs e) {
        // .....
        string MyString = "ABC DEF GHI";
        // .....
        float StrWidth = e.Graphics.MeasureString(MyString, this.Font).Width;
        // .....
    }
    

    Aber die so berechnete Länge des String stimmt nicht mit der gezeichneten Länge überein, selbst wenn die PageUnit-Property von e.Graphics auf Pixel steht. Die Ausgabe auf dem Monitor war bei mir immer deutlich kürzer (ca. 5 Pixels) als die berechnete Länge; Rundungsdifferenzen kann ich da ja wohl ausschließen.

    Warum liefert MeasureString nicht die korrekte Länge?



  • Such' mal in der MSDN, das ist ein Schätzwert, imho.



  • Naja, ich habe schon gehofft, dass es dem System bei vorgegebenem Drawing-Kontext (Graphics) und definiertem Font möglich sein sollte, die korrekte Länge der Bildschirmdarstellung in Pixeln zu liefern.



  • Benutzt du .NET 2.0, dann nimm den TextRenderer. Dazu ein Zitat aus der MS-C#-NG:

    [Zitat]
    Seit NET 2.0 _kann_ nun wieder Text zusätzlich mittels GDI (ohne plus)
    ausgegeben werden. Die Ausgabe erfolgt mittels TextRenderer.DrawText()
    und sollte _dann auch_ mittels TextRenderer.MeasureText() entsprechend
    berechnet werden. Vgl. hier etwa:

    [TextRendering in .NET 2.0]
    http://headwriteline.blogspot.com/2006_04_01_archive.html

    [Use Compatible TextRendering - Compatible with whaaaaaat?]
    http://blogs.msdn.com/jfoscoding/archive/2005/10/13/480632.aspx

    Soweit ich dies an Beispielen bisher selbst überprüft habe gilt
    folgendes:

    Neue Controls werden stets mittels GDI ausgeben (Beispiel: Das von
    Frank genannte DataGridView). Alte Controls können sowohl mittels GDI
    als auch mittels GDI+ ausgegeben werden. Diese Controls verfügen
    scheinbar nun über die UseCompatibleTextRendering-Eigenschaft. Ist
    diese mittels Programmcode gesetzt, gilt diese Einstellung
    entsprechend dieser Vorgabe. (true -> GDI+, false -> GDI). Ist diese
    Eigenschaft nicht gesetzt, gilt die Einstellung die mittels
    Application.SetCompatibleTextRenderingDefault(...); gesetzt wurde. Die
    Windows-Anwendung-Projektvorlage setzt dies standardmäßig auf false.
    Auch hier gilt: false -> GDI, true -> GDI+. Interessant ist nun, dass
    diejenigen, die leere Projektvorlagen als Ausgangspunkt benutzen
    (mache ich üblicherweise so) nun i.d.R.
    Application.SetCompatibleTextRenderingDefault(...); nicht setzen. Dann
    verhält sich die Ausgabe so, als wenn
    Application.SetCompatibleTextRenderingDefault mit _true_ aufgerufen
    wurde (also genau umgekehrt zum Verhalten mittels der
    Windows-Anwendung-Projektvorlage).

    Zusammenfassend gilt:

    Application.SetCompatibleTextRenderingDefault( true )
    bzw. dasControl.UseCompatibleTextRendering = true -> GDI+
    Ausgabe mittels Graphics.DrawString(...)
    Messen mittels Graphics.MeasureString(...)

    SetCompatibleTextRenderingDefault( false )
    bzw. dasControl.UseCompatibleTextRendering = false-> GDI
    Ausgabe mittels TextRenderer.DrawText(...)
    Messen mittels TextRenderer.MeasureText(...)

    Nachvollziehen kann man dies leicht an einem Label mit dem Text
    "Hallo, ich bin ein String".
    GDI+ -> Label-Breite 120, Graphics.MeasureString ergibt 119,3708
    GDI -> Label-Breite 115, TextRenderer.MeasureText ergibt 115.
    (jeweils mittels SetCompatibleTextRenderingDefault oder
    UseCompatibleTextRendering setzen).
    [/Zitat]



  • @michme: Es wäre sehr nett, wenn Du bei Deinem Zitat auch die Quelle bzw. den Autor angegeben hättest. Gehört sich einfach so. Ich liefere das mal nach, der Beitrag stammt von Hans-Heinrich Breuer.



  • Hast recht, ich werds mir merken.



  • Ja, vielen Dank für die ausführliche Info.

    (Wie Ihr bestimmt gemerkt habt, hatte ich mehrere (verschiedene) Anfragen laufen. Ich hoffe - und bin zuversichtlich - dass ich bald auch hilfreich mitmachen kann.

    mfg


Anmelden zum Antworten