69

我正在使用 .NETCF (Windows Mobile)Graphics类和将DrawString()单个字符呈现到屏幕上的方法。

问题是我似乎无法将其正确居中。无论我为字符串渲染位置的 Y 坐标设置什么,它总是低于该值,并且文本大小越大 Y 偏移量越大。

例如,在文本大小为 12 时,偏移量约为 4,但在 32 时,偏移量约为 10。

我希望角色垂直占据它正在绘制的大部分矩形并水平居中。这是我的基本代码。this正在引用它被绘制的用户控件。

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);

是的,我知道我可以使用标签控件并使用它来设置居中,但我确实需要使用Graphics类手动执行此操作。

4

6 回答 6

90

我想为 StringFormat 对象添加另一票。您可以简单地使用它来指定“中心,中心”,文本将在矩形或提供的点中居中绘制:

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

然而,在 CF 中存在一个问题。如果您对这两个值都使用 Center,那么它会关闭 TextWrapping。不知道为什么会发生这种情况,这似乎是 CF 的一个错误。

于 2008-08-25T17:49:38.463 回答
66

要对齐文本,请使用以下命令:

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

请注意,此处的文本在给定的范围内对齐。在此示例中,这是 ClientRectangle。

于 2008-10-13T13:15:08.237 回答
22

通过结合我得到的建议,我想出了这个:

    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();
        }
    }

到目前为止,这完美无缺。

我唯一要更改的是将 FindBestFitFont() 调用移至 OnResize() 事件,这样我就不会在每次绘制字母时都调用它。只有在控件大小发生变化时才需要调用它。为了完整起见,我只是将它包含在函数中。

于 2008-08-11T19:03:59.803 回答
13

要绘制居中文本:

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

确定填充区域的最佳字体大小有点困难。我发现一个可行的方法是反复试验:从大字体开始,然后反复测量字符串并缩小字体直到适合为止。

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();
  }
}

您可以将其用作:

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)
于 2008-08-11T18:22:16.223 回答
5

这是一些代码。这假定您在窗体或 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));

从您的帖子中,听起来 ClientRectangle 部分(例如,您没有使用它)是给您带来困难的原因。

于 2008-08-11T17:50:41.217 回答
3

您可以使用StringFormat传递给DrawString方法的对象实例来使文本居中。

请参阅Graphics.DrawString 方法StringFormat 类

于 2008-08-11T17:49:31.623 回答