2011-09-09 143 views
2

我想在我的文本框的子類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號,例如:

正如你可以看到,線切割線穿過0,當改爲它應該是的0

權編輯:

我忘了提,「保證金」是WinForms.Label。

+0

猜猜你將有不同的'TextFormatFlags'玩。 – leppie

+0

首先要排除的是它是常數還是乘法。如果將它設置爲40,它是否與相同數量的結束字符重疊?如果是這樣,那麼顯然'LeftMargin'需要一些調整。 –

+0

達明:如果我說'margin.Left = charWidth + LEFTMARGIN;',我也有同樣的問題:宋體是好的,但索拉不是。 – Tom

回答

2

好的,我解決了這個問題。我不得不通過發送EM_GETMARGINS(而不僅僅是假設左邊距爲2,它適用於只是某些字體/大小)來獲得文本框的左邊距,和我有這個base.OnFontChanged(e);做我OnFontChanged覆蓋。謝謝,所有的幫助。

0

我想嘗試只需設置Width

Width = charWidth * 80 + LeftMargin; 

我從會自動調整大小基於文本的寬度TextBox創建一個派生類。它與你所提到的兩種字體:

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

什麼寬度?我不能只設置文本框的寬度,因爲我正在創建右邊距,如截圖所示。 – Tom

+0

所以你想要一個大小相等的左右邊距?也許你想要的屏幕截圖會有所幫助 – SwDevMan81

+0

我只想要一個右邊距。 「LeftMargin」是TextBox的自然左邊距。現在我已經在10號包含了Courier New的截圖,它展示了應該看起來如何。 – Tom

1

使用Graphics.MeasureString代替。結果是SizeF,而不是像TextRenderer方法返回的Size

+0

如果我使用「SizeF size = graphics.MeasureString(new string('m',80),Font);」,我得到同樣的問題(Courier New與Consolas不同) – Tom

+0

IIRC,你需要一些特定的StringFormat設置。將尋找我寫回來處理這個問題的代碼。 – leppie

+0

謝謝。我現在似乎已經解決了這個問題,正如我對這個問題的回答中所提到的。 – Tom

1

但是,你應該使用剛剛固定長度的字體,因爲焦炭的寬度「我」是不是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是這裏的關鍵參數,沒有它們 - 測量不起作用。謝謝! –