Thursday, August 11, 2016

Windows Forms: Determining the size required to display a string (Graphics MeasureString)

Before the age of computers, typewriters could write pica (10 letters per-inch) and elite (12 letters per-inch). With fixed width fonts it was clear how much text took how much space.  That was decades ago so consider the case of a Windows Forms a TextBox where the fonts are not fixed width and there is support for different font sizes. There needs to be a way to insurance the size of the TextBox is large enough (the Size property) to accommodate the length of the text assigned to the TextBox's Text property.

The Windows forms application below is not very creative. A numeric up/down control specifies the number of characters to display in a TextBox. Below 1 character (a zero) is displayed in the TextBox:


Below 2 characters (a zero and a one) are displayed in the TextBox:




Below 6 characters (a zero through five) are assigned to the TextBox but the number five is not displayed as the TextBox is not off sufficient width::


The code associated with the flawed application is follows:

public partial class ShowWhatIsNotSeen : Form
{
  public ShowWhatIsNotSeen()
  {
    InitializeComponent();
  }

  private void HandleTextToShow()
  {
    textBoxDisplayData.Text = String.Empty;
    for (int i = 0; i < numericUpDownDataToShow.Value; i++)
    {
      textBoxDisplayData.Text += i.ToString();
    }
  }

  private void numericUpDownRowsToShow_ValueChanged(object sender, 
                                                    EventArgs e)
  {
    HandleTextToShow();
  }

  private void ShowWhatIsNotSeen_Load(object sender, EventArgs e)
  {
    HandleTextToShow();
  }
}

The following code demonostrates the Graphics class's MeasureString is used to insure the TextBox is large enough to hold the string assigned to its Text property:

    private void HandleTextToShow()
    {
      textBoxDisplayData.Text = String.Empty;
      for (int i = 0; i < numericUpDownDataToShow.Value; i++)
      {
        textBoxDisplayData.Text += i.ToString();
      }

      using (Graphics graphics = CreateGraphics())
      {
        SizeF size = 
           graphics.MeasureString(textBoxDisplayData.Text, 
                                  textBoxDisplayData.Font);
        int width = (int)Math.Ceiling(size.Width) + 
                    textBoxDisplayData.Margin.Left + 
                    textBoxDisplayData.Margin.Right;
        int height = (int)Math.Ceiling(size.Height) + 
                     textBoxDisplayData.Margin.Top + 
                     textBoxDisplayData.Margin.Bottom;

        textBoxDisplayData.Size = new Size(width, height);
      }
    }

No comments :

Post a Comment