2008-08-11 16 views
38

私は.NETCF(Windows Mobile)GraphicsクラスとDrawString()メソッドを使用して、1文字を画面にレンダリングしています。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

DrawStringメソッドに渡されたStringFormatオブジェクトのインスタンスを使用して、テキストを中央に配置することができます。

Graphics.DrawString MethodおよびStringFormat Classを参照してください。

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

は、もう少し難しいです。私が見つけた働きかけの1つは試行錯誤です。大きなフォントで始め、繰り返し文字列を測定し、それが収まるまでフォントを縮小します。

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はもっと精密で、それから単純なegraphics.drawstringがたくさんありがとう、私から投票する:) –

54

StringFormatオブジェクトに別の投票を追加したいと思います。 CF.でこれで1つの問題があるしかし

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

: あなたは、単に「センター、センター」とテキストが提供長方形またはポイントで集中的に描画されますを指定するためにこれを使用することができます両方の値にCenterを使用すると、TextWrappingがオフになります。なぜこのようなことが起こるか分かりませんが、CFのバグであるようです。

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

ここにテキストが与えられた境界に整列されていることに注意してください:以下を使用したテキストを整列するために

40

。このサンプルでは、​​これはClientRectangleです。

+0

Chris'sソリューションは素晴らしいです。あなたが水平の中心で、任意の位置に垂直に設定したい場合BTW:e.Graphics.DrawString( "My String"、this.Font、Brushes.Black、e.CellBounds.Width/2、y、sf); // yは垂直位置です – camino

関連する問題