开发者

Why is TextRenderer.MeasureText inaccurate here?

I'm trying to draw a margin at 80 characters in my TextBox subclass. Here is my code:

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

This works fine for certain fonts 开发者_如何学Cat certain sizes (e.g., Courier New at size 10):

Why is TextRenderer.MeasureText inaccurate here?

But with other fonts this turns out to be slightly inaccurate. Here is a screenshot with Consolas at size 12, for example:

Why is TextRenderer.MeasureText inaccurate here?

As you can see, the line cuts through the 0, when instead it should be to the right of the 0.

EDIT:

I forgot to mention that 'margin' is a WinForms.Label.


Use Graphics.MeasureString instead. The result is SizeF and not Size like the TextRenderer's method returns.


Okay, I solved the problem. I had to get the left margin of the TextBox by sending EM_GETMARGINS (rather than just assuming that the left margin is 2, which works for only some fonts/sizes), and I had to do this after base.OnFontChanged(e); in my OnFontChanged override. Thanks, all, for the assistance.


But, you should use just fixed length font, because width of char 'I' is different than width of char 'M'. Or if you know string in textbox. You can change code:

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

        margin.Left = stringWidth;


I would try just setting the Width

Width = charWidth * 80 + LeftMargin;

I created a derived class from TextBox that will auto size the width based on the Text. It works with both fonts you mentioned:

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

Note: In my project, the Margin.Left and Margin.Right are set to 3

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜