web-dev-qa-db-fra.com

Mesurer une chaîne sans utiliser d'objet graphique?

J'utilise des pixels comme unité pour ma police. À un endroit, j'effectue un test de détection pour vérifier si l'utilisateur a cliqué dans le rectangle de délimitation d'un texte à l'écran. J'ai besoin d'utiliser quelque chose comme MeasureString pour cela. Malheureusement, le code qui effectue le test d'accès se trouve dans une bibliothèque qui n'a pas accès à un objet Graphics ni même à Control.

Comment obtenir le cadre de sélection d'une chaîne en fonction de la police sans utiliser la classe Graphics? Pourquoi ai-je même besoin d'un objet Graphics lorsque ma police est en pixels?

39
Agnel Kurian

Si vous avez une référence à System.Windows.Forms, essayez d'utiliser la classe TextRenderer. Il existe une méthode statique (MeasureText) qui prend la chaîne et la police et renvoie la taille. MSDN Link

46
Jarrod

Vous n'avez pas besoin d'utiliser l'objet graphique que vous utilisez pour effectuer le rendu pour effectuer la mesure. Vous pouvez créer une classe d'utilitaire statique:

public static class GraphicsHelper
{
    public static SizeF MeasureString(string s, Font font)
    {
        SizeF result;
        using (var image = new Bitmap(1, 1))
        {
            using (var g = Graphics.FromImage(image))
            {
                result = g.MeasureString(s, font);
            }
        }

        return result;
    }
}

Cela peut valoir la peine, en fonction de votre situation, de définir également le dpi de l'image bitmap.

23
NerdFury

La méthode MeasureString de la réponse @NerdFury donnera une largeur de chaîne supérieure à celle attendue. Des informations supplémentaires vous permettent de trouver ici . Si vous souhaitez mesurer uniquement la longueur physique, veuillez ajouter ces deux lignes: 

g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
result = 
  g.MeasureString(measuredString, font, int.MaxValue, StringFormat.GenericTypographic);
10
Anton Putov

Cet exemple illustre parfaitement l'utilisation de FormattedText. FormattedText fournit un contrôle de bas niveau pour le dessin de texte dans les applications Windows Presentation Foundation (WPF). Vous pouvez l'utiliser pour mesurer la largeur d'une chaîne avec une police particulière sans utiliser d'objet Graphics.

public static float Measure(string text, string fontFamily, float emSize)
{
    FormattedText formatted = new FormattedText(
        item, 
        CultureInfo.CurrentCulture, 
        System.Windows.FlowDirection.LeftToRight, 
        new Typeface(fontFamily), 
        emSize, 
        Brushes.Black);

    return formatted.Width;
}

Inclure les bibliothèques WindowsBase et PresentationCore.

1
Jacob Raines

Ce n’est peut-être pas une répétition des autres, mais mon problème était également l’objet Graphics indésirable. Après avoir écouté les frustrations ci-dessus, j'ai simplement essayé:

Size proposedSize = new Size(int.MaxValue, int.MaxValue);
TextFormatFlags flags = TextFormatFlags.NoPadding;
Size ressize = TextRenderer.MeasureText(content, cardfont, proposedSize, flags);

(où 'contenu' est la chaîne pour mesurer et cardfont la police dans laquelle elle se trouve)

... et avait de la chance. Je pourrais utiliser le résultat pour définir la largeur de ma colonne dans VSTO.

0
Peter Høgstedt