2008-08-11 77 views
38

我使用.NETCF(Windows Mobile)Graphics類和DrawString()方法將單個字符呈現在屏幕上。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班。

回答

13

通過對我的建議組合,我想出了這個:

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()事件,以便每次繪製字母時都不會調用它。只有在控件大小發生變化時才需要調用它。我只是將它包含在函數中以獲得完整性。

1

這是一些代碼。這假定您正在窗體或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部分(因爲您不使用它)是什麼給你帶來困難。

8

要繪製居中文本:

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) 
+0

謝謝你展示其他方式來繪製東西,它真的幫助我與中心對齊問題結果TextRenderer.DrawText更精確,然後一個簡單的e.graphics.drawstring非常感謝,從我投票:) – 2015-02-03 12:55:53

54

我想爲StringFormat對象添加另一個投票。 您可以使用此簡單地指定「中心,中心」和文本將集中在矩形中畫或點提供:

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

但是這裏有一個問題與此的CF.如果您使用Center作爲兩個值,則會關閉TextWrapping。不知道爲什麼會發生這種情況,這似乎是CF的一個錯誤。

40

要對齊文本使用以下命令:

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

請注意,這裏的文本在給定的範圍對齊。在這個例子中,這是ClientRectangle。

+0

克里斯的解決方案非常棒。順便說一句,如果你想設置在水平中心,但在任何位置垂直:e.Graphics.DrawString(「我的字符串」,this.Font,Brushes.Black,e.CellBounds.Width/2,Y,SF); // y是垂直位置 – camino 2017-01-27 13:55:03