69

.NETCF(Windows Mobile)GraphicsクラスとDrawString()メソッドを使用して、画面に1文字をレンダリングしています。

問題は、それを適切に中央に配置できないように見えることです。文字列レンダリングの場所の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 オブジェクトにもう 1 票追加したいと思います。これを単に「center, center」と指定するために使用でき、テキストは指定された長方形または点の中央に描画されます。

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

ただし、CF にはこれに関する 1 つの問題があります。両方の値に 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);

領域を埋めるための最適なフォントサイズを決定するのは少し難しいです。私が見つけた実用的な方法の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)
于 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 に答える