C# Does a label ignore whitespaces when querying MeasureString?

301 Views Asked by At

I have been trying to find an error in a ticker tape type application. Hopefully this background is not to long.

Background: The ticker tape needs to display characters starting from the right and then scroll to the left. I need to use a label (or do I?) due to the application being windows forms and need background colour to be transparent. Had issues using different controls. The control size and font is not known and must be calculated at run time.

The ticker tape has the main scenarios firstly the start where we need to PAD to left of the displaying string.

The middle where we remove front characters and add character still need to display.

The end which should PAD to the right moving the last character a long until last character is all to the left. The message is then complete.

I have 2 function that this questions is regarding:

1) That calculates the size of the display text using the control and fonts.

2) The meat of the application the function that returns the display text.

Problem:

The start and middle scenarios work perfectly, the end does not work if I pad with spaces, but does If I use any other visible character like "." it works.

Size Function:

 Label tstLabel = new Label();
 tstLabel.Size = DisplaySize;
 tstLabel.Font = new Font(currentMessage.Font, currentMessage.Fonsize);
 var g = Graphics.FromHwnd(tstLabel.Handle);
 SizeF size = g.MeasureString(text, tstLabel.Font);
 return size;

Display Text function:

SizeF spaceSize = getSize(" ");
string text = "";
if(currentCharacter < currentMessage.MessageText.Length )
{
     text = currentMessage.MessageText.Substring(0, currentCharacter + 1);
     SizeF displayTextSize = getSize(text);
     if (displayTextSize.Width <= DisplaySize.Width)
     {
          int numSpaces = Convert.ToInt32((DisplaySize.Width - displayTextSize.Width) / spaceSize.Width);
          text = text.PadLeft(numSpaces + text.Length, ' ');
                        currentCharacter++;
                        #endregion
                    }
                    else
                    {
                        #region Pop char off front
                        bool keepPadding = true;
                        do
                        {
                            text = text.Substring(1, text.Length - 1);
                            displayTextSize = getSize(text);
                            if (displayTextSize.Width <= DisplaySize.Width)
                            {
                                keepPadding = false;
                            }
                        } while (keepPadding);
                        currentCharacter++;
                        #endregion
                    }
                }
                else
                {
                    #region Pop char off front and Pad to right
                    text = currentMessage.MessageText.PadRight(currentCharacter+1,'.');
                    bool keepPadding = true;
                    do
                    {
                        text = text.Substring(1, text.Length - 1);
                        SizeF endTextSize = getSize(text);
                        if (endTextSize.Width <= DisplaySize.Width)
                        {
                            if ((DisplaySize.Width - endTextSize.Width) > spaceSize.Width)
                            {
                                do
                                {
                                    text += ".";
                                    endTextSize = getSize(text);
                                    currentCharacter++;
                                } while ((DisplaySize.Width - endTextSize.Width) > spaceSize.Width);
                            }
                            keepPadding = false;
                        }
                    } while (keepPadding);
                    currentCharacter++;
                    if (checkMessage(text))
                        nextMessage = true;
                }
                return text;

The Question:

When doing the function below on a label and there whitespaces behind the text why does it return the same size?

SizeF size = g.MeasureString(text, tstLabel.Font);

2

There are 2 best solutions below

0
On
SizeF size = g.MeasureString(text, tstLabel.Font, tstLabel.ClientSize,
    new StringFormat(StringFormatFlags.MeasureTrailingSpaces));

However, if you want to use the same rendering as WinForms, use TextRenderer.MeasureText and TextRenderer.DrawText instead. Starting with .NET 2.0 Graphics.MeasureString and DrawString are used only when UseCompatibleTextRendering property is true.

0
On

This fixes the Issue relating to MeasureString:

 StringFormat strFormat = new StringFormat(StringFormat.GenericTypographic)
                        {
                            FormatFlags = StringFormatFlags.MeasureTrailingSpaces

                        };
                        size = g.MeasureString(text, tstLabel.Font, tstLabel.Size.Width, strFormat);

Thanks GSerg!