web-dev-qa-db-fra.com

Déterminer la taille de l'étiquette en fonction de la quantité de texte et de la taille de la police dans Winforms/C #

J'aimerais savoir s'il existe une meilleure approche de ce problème. Je veux redimensionner une étiquette (verticalement) pour accueillir une certaine quantité de texte. Mon étiquette a une largeur fixe (environ 60 caractères avant d’être enroulée), environ 495 pixels. La police a également une taille fixe (12 points autant que je sache), mais pas le texte. 

Ce que je veux faire, c'est augmenter la hauteur de l'étiquette lorsqu'il y a une "NewLine" ou que le texte doit être renvoyé à la ligne; L'idée est que le texte est entièrement visible dans l'étiquette. La taille automatique ne fonctionne pas car elle va croître en largeur et non en hauteur. 

Bien sûr, je pouvais compter le nombre de NewLines et ajouter: Newlines * LineHeight, puis, étant donné que je réussis à mettre 60 caractères par ligne, divisez simplement le nombre de caractères et ajoutez autant de pixels LineHeight que nécessaire.

Je me demandais s'il y avait une manière plus professionnelle de le faire. Est-ce que mon approche est trop "boiteuse"?

Merci d'avance.

39
Martin Marconcini

Que diriez-vous de Graphics.MeasureString, avec la surcharge qui accepte une chaîne, la police et la largeur maximale? Ceci retourne une SizeF, vous pouvez donc arrondir la Height.

        using(Graphics g = CreateGraphics()) {
            SizeF size = g.MeasureString(text, lbl.Font, 495);
            lbl.Height = (int) Math.Ceiling(size.Height);
            lbl.Text = text;
        }
90
Marc Gravell

System.Drawing.Graphics a une méthode MeasureString que vous pouvez utiliser à cette fin. Utilisez la surcharge qui prend une chaîne, une police et un paramètre int "width"; Ce dernier paramètre spécifie la largeur maximale autorisée pour la chaîne. Utilisez la largeur définie de votre étiquette pour ce paramètre.

MeasureString retourne un objet SizeF. Utilisez la propriété Height de cet objet renvoyé pour définir la hauteur de votre étiquette.

Remarque: pour obtenir un objet Graphics à cette fin, vous pouvez appeler this.CreateGraphics.

33
MusiGenesis

Graphics.MeasureString () va probablement vous aider.

C'est également l'un des seuls cas d'utilisation de l'appel de Control.CreateGraphics ()!

9
Quibblesome
Size maxSize = new Size(495, int.MaxValue);
_label.Height = TextRenderer.MeasureText(_label.Text , _label.Font, maxSize).Height;
5
Hacko

Cette "réponse" est pour référence future et pour combattre l'hypothèse initiale que AutoSize = true implique qu'elle (une étiquette WinForms) ne grandira jamais.

Le lien suivant montre les différents effets de AutoSize = true avec d'autres propriétés telles que MaximumSize. En fonction de l'utilisation attendue de la question, il peut être approprié de suivre l'une de ces approches.

http://blogs.msdn.com/jfoscoding/articles/478299.aspx

2
user166390

J'ai posté un contrôle utilisateur qui résout ce problème dans la réponse acceptée ici: Police à l'échelle automatique dans un contrôle TextBox afin qu'il soit aussi grand que possible et qu'il tienne dans les limites de la zone de texte

Le contrôle étend RichTextBox. Il a une méthode: ScaleFontToFit qui redimensionnera automatiquement la police pour ajuster tout le texte.

La chose intéressante est qu'il respecte la propriété multiligne. Si c'est vrai, les mots peuvent envelopper, sinon ce n'est pas le cas.

1
blak3r

Dans certains cas où vous devez utiliser un cadre compact, qui ne comporte aucune méthode de remplacement pour MeasureString (), vous pouvez envisager de calculer vous-même la hauteur.

private int YukseklikAyarla(string p, Font font, int maxWidth)
    {
        int iHeight = 0;
        using (Graphics g = CreateGraphics())
        {
            var sizes = g.MeasureString(p, font); // THE ONLY METHOD WE ARE ALLOWED TO USE
            iHeight = (int)Math.Round(sizes.Height);
            var multiplier = (int)Math.Round((double)sizes.Width) / maxWidth; // DIVIDING THE TEXT WIDTH TO SEE HOW MANY LINES IT CAN HAS
            if (multiplier > 0)
            {
                iHeight = (int)(iHeight * (multiplier + 1)); // WE ADD 1 HERE BECAUSE THE TEXT ALREADY HAS A LINE
            }
        }
        return iHeight;
    }
0
Doğa Gençer

Existe-t-il un inconvénient à utiliser la classe TextRenderer pour mesurer la chaîne (comme dans la réponse de Marc) au lieu de passer par le travail pour créer un objet Graphics, etc.?

0
jean

Les 60 caractères sont peut-être valables pour votre texte d’essai, mais tous les caractères n’ont pas la même largeur. Par exemple, comparez
llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.
et
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

Ils ont tous les deux 60 caractères et ont pourtant des largeurs très différentes.

0
Yuliy

Selon cet article , vous devez utiliser TextRenderer si vous allez utiliser un contrôle Windows Form pour la sortie finale. TextRenderer et Graphics.MeasureString donneront des résultats différents, utilisez donc celui qui correspond au mode de sortie final. 

0
Barry Keller