2011-09-09 14 views
2

私はTextBoxサブクラスで80文字の余白を描こうとしています。ここに私のコードは次のとおりです。ここでTextRenderer.MeasureTextが不正確なのはなぜですか?

class FooTextBox : TextBox 
{ 
    ... 

    void UpdateMarginPosition() 
    { 
     using (Graphics graphics = CreateGraphics()) { 
      int charWidth = TextRenderer.MeasureText(graphics, "M", Font, 
       ClientSize, TextFormatFlags.NoPadding).Width; 

      const int LeftMargin = 2; 
      margin.Left = charWidth * 80 + LeftMargin; 
     } 
    } 
} 

これは、特定のサイズ(例えば、サイズ10でクーリエ新)で特定のフォントのため正常に動作します:

しかし、他のフォントで、これはわずかであることが判明します不正確ですここではサイズ12でConsolasとスクリーンショットには、例えば、次のとおりです。

あなたが見ることができるように代わり、それは0

の右にあるべきとき、ラインは、0切り裂きます編集:

'margin'はWinForms.Labelです。

+0

異なる 'TextFormatFlags'で遊ぶ必要があると思います。 – leppie

+0

最初に除外すべきことは、その定数か乗算かどうかです。それを40に設定すると、同じ文字数で終了文字が重なりますか?もしそうなら、明らかに 'LeftMargin'はいくらかの調整が必要です。 –

+0

Damien:もしmargin.Left = charWidth + LeftMargin;と言うと、同じ問題があります:Courier Newは問題ありませんが、Consolasはそうではありません。 – Tom

答えて

2

さて、私は問題を解決しました。私はEM_GETMARGINSを送信してTextBoxの左余白を取得する必要がありました(左の余白は2のフォント/サイズでしか動作しません)。base.OnFontChanged(e);をOnFontChangedでオーバーライドしました。ご協力いただきありがとうございます。

0

は、私はちょうど私が幅テキストで自動サイズ基づきますTextBoxから派生したクラスを作成しWidth

Width = charWidth * 80 + LeftMargin; 

を設定しようとするだろう。

public class MyTextBox : TextBox 
{ 
    public override string Text 
    { 
     get 
     { 
     return base.Text; 
     } 
     set 
     { 
     base.Text = value; 
     UpdateTextboxWidth(); 
     } 
    } 

    void UpdateTextboxWidth() 
    { 
     using (Graphics graphics = CreateGraphics()) 
     { 
     int text_width = TextRenderer.MeasureText(graphics, base.Text, Font, 
      ClientSize, TextFormatFlags.NoPadding).Width; 

     Width = text_width + Margin.Left + Margin.Right; 
     } 
    } 
} 

注:それはあなたが言及した両方のフォントで動作します私のプロジェクトでは、Margin.LeftMargin.Rightではなく、3

+1

何の幅ですか?スクリーンショットに示すように、右余白を作成しているので、TextBoxの幅を設定するだけではありません。 – Tom

+0

同じサイズの左右のマージンが必要ですか?たぶんあなたが望むもののスクリーンショットが役に立つでしょう – SwDevMan81

+0

私は右のマージンがほしいです。 "LeftMargin"は、TextBoxの自然な左マージンです。私は今、Courier Newのスクリーンショットをサイズ10で表示しました。これは、どのように見えるかを示しています。 – Tom

1

使用Graphics.MeasureStringに設定されています。結果はSizeFであり、TextRendererのメソッドが返すようにSizeではありません。

+0

"SizeF size = graphics.MeasureString(新しい文字列( 'm'、80)、Font);"を使用すると同じ問題が発生します(Courier NewはConsolasとは異なります)。 – Tom

+0

IIRCでは、特定のStringFormat設定が必要です。これを処理するために私が数年前に書いたコードを探します。 – leppie

+0

ありがとうございます。私はこの問題に私の答えで述べたように、今問題を解決したようです。 – Tom

1

しかし、char 'I'の幅がchar 'M'の幅と異なるため、固定長フォントだけを使用する必要があります。または、テキストボックスの文字列を知っている場合。あなたはコードを変更することができます:

int stringWidth = TextRenderer.MeasureText(graphics, this.text, Font, 
      ClientSize, TextFormatFlags.NoPadding).Width; 

     margin.Left = stringWidth; 
+0

Courier NewとConsolas *は固定幅フォントなので、このコメントはその質問に答えません。 – Tom

+0

ClientSizeとTextFormatFlags.NoPaddingはここでの重要な引数です。ありがとう! –

関連する問題