Question

Je suis en utilisant le .NETCF (Windows Mobile) Graphics la classe et le DrawString() méthode pour rendre un caractère unique à l'écran.

Le problème est que je n'arrive pas à l'obtenir centré correctement.Peu importe ce que j'ai mis pour la coordonnée Y de l'emplacement de la chaîne de rendu, il s'en sort toujours inférieur et plus la taille du texte la plus le décalage Y de la.

Par exemple, au texte de taille 12, le décalage est d'environ 4, mais à 32 le décalage est d'environ 10.

Je veux le caractère à la verticale prendre la plus grande partie du rectangle, c'est être attiré et être centré horizontalement.Voici mon code de base. this fait référence à l'utilisateur de contrôler c'est d'être aspiré.

Graphics g = this.CreateGraphics();

float padx = ((float)this.Size.Width) * (0.05F);
float pady = ((float)this.Size.Height) * (0.05F);

float width = ((float)this.Size.Width) - 2 * padx;
float height = ((float)this.Size.Height) - 2 * pady;

float emSize = height;

g.DrawString(letter, new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular),
            new SolidBrush(Color.Black), padx, pady);

Oui, je sais qu'il est l'étiquette de contrôle que je pourrais utiliser à la place et régler le centrage, mais j'ai réellement besoin de le faire manuellement avec la Graphics classe.

Était-ce utile?

La solution 3

Grâce à une combinaison de suggestions que j'ai eu, j'ai trouvé ceci:

    private void DrawLetter()
    {
        Graphics g = this.CreateGraphics();

        float width = ((float)this.ClientRectangle.Width);
        float height = ((float)this.ClientRectangle.Width);

        float emSize = height;

        Font font = new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular);

        font = FindBestFitFont(g, letter.ToString(), font, this.ClientRectangle.Size);

        SizeF size = g.MeasureString(letter.ToString(), font);
        g.DrawString(letter, font, new SolidBrush(Color.Black), (width-size.Width)/2, 0);

    }

    private Font FindBestFitFont(Graphics g, String text, Font font, Size proposedSize)
    {
        // Compute actual size, shrink if needed
        while (true)
        {
            SizeF size = g.MeasureString(text, font);

            // It fits, back out
            if (size.Height <= proposedSize.Height &&
                 size.Width <= proposedSize.Width) { return font; }

            // Try a smaller font (90% of old size)
            Font oldFont = font;
            font = new Font(font.Name, (float)(font.Size * .9), font.Style);
            oldFont.Dispose();
        }
    }

Jusqu'à présent, cela fonctionne parfaitement.

La seule chose que je voudrais changer est de déplacer le FindBestFitFont() appel à la OnResize() de l'événement, de sorte que je ne suis pas de l'appeler à chaque fois que je dessine une lettre.Il ne doit être appelée lorsque le contrôle changements de taille.J'ai juste inclus dans la fonction de l'exhaustivité.

Autres conseils

Je voudrais ajouter un autre vote pour l'objet StringFormat.Vous pouvez l'utiliser simplement pour préciser les "le centre, centre" et le texte sera rédigé de manière centralisée dans le rectangle ou points:

StringFormat format = new StringFormat();
format.LineAlignment = StringAlignment.Center;
format.Alignment = StringAlignment.Center;

Cependant il y a un problème avec cette FC.Si vous utilisez le Centre pour les deux valeurs puis il tourne TextWrapping off.Aucune idée de pourquoi cela se produit, il semble être un bug avec le CF.

Pour aligner un texte, utilisez les éléments suivants:

StringFormat sf = new StringFormat();
sf.LineAlignment = StringAlignment.Center;
sf.Alignment = StringAlignment.Center;
e.Graphics.DrawString("My String", this.Font, Brushes.Black, ClientRectangle, sf);

Veuillez noter que le texte est aligné dans les limites.Dans cet exemple c'est le ClientRectangle.

Pour dessiner un texte centré:

TextRenderer.DrawText(g, "my text", Font, Bounds, ForeColor, BackColor, 
  TextFormatFlags.HorizontalCenter | 
  TextFormatFlags.VerticalCenter |
  TextFormatFlags.GlyphOverhangPadding);

La détermination optimale de la taille de la police pour remplir une zone est un peu plus difficile.Un travail soultion j'ai trouvé de l'essai-et-erreur:commencer avec une grosse police, puis d'effectuer la mesure de la corde et réduire la police jusqu'à ce qu'il s'adapte.

Font FindBestFitFont(Graphics g, String text, Font font, 
  Size proposedSize, TextFormatFlags flags)
{ 
  // Compute actual size, shrink if needed
  while (true)
  {
    Size size = TextRenderer.MeasureText(g, text, font, proposedSize, flags);

    // It fits, back out
    if ( size.Height <= proposedSize.Height && 
         size.Width <= proposedSize.Width) { return font; }

    // Try a smaller font (90% of old size)
    Font oldFont = font;
    font = new Font(font.FontFamily, (float)(font.Size * .9)); 
    oldFont.Dispose();
  }
}

Vous pouvez utiliser ce que:

Font bestFitFont = FindBestFitFont(g, text, someBigFont, sizeToFitIn, flags);
// Then do your drawing using the bestFitFont
// Don't forget to dispose the font (if/when needed)

Vous pouvez utiliser une instance de la StringFormat objet passé dans le DrawString méthode pour centrer le texte.

Voir Les graphiques.Cordon De Serrage Méthode et StringFormat Classe.

Voici une partie du code.Cela suppose que vous faites cela sur une forme, ou un UserControl.

Graphics g = this.CreateGraphics();
SizeF size = g.MeasureString("string to measure");

int nLeft = Convert.ToInt32((this.ClientRectangle.Width / 2) - (size.Width / 2));
int nTop = Convert.ToInt32((this.ClientRectangle.Height / 2) - (size.Height / 2));

À partir de votre post, il semble que les ClientRectangle partie (vous ne l'utilisez pas) est ce que vous offre une difficulté.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top