I have a winform application on which I place a label. I change the text of the label dynamically from a background thread. The text change fires an event that is supposed to resize the label. Everything works fine except the string length I measure is incorrect and consequently the client size of the label is incorrect.
protected void progressInfo_TextChanged(object sender, EventArgs e)
{
// Auto size label to fit the text
// ... create a Graphics object for the label
Graphics g_progressInfo = this.progressInfo.CreateGraphics();
// ----------------
// Set up string.
string text1 = "Reading data from input data file ... inputData";
Font stringFont = new System.Drawing.Font("Verdana", 8,
System.Drawing.FontStyle.Regular);
Size textSize = TextRenderer.MeasureText(text1, stringFont);
TextRenderer.DrawText(g_progressInfo, text1, stringFont,
new Rectangle(new Point(10, 10), textSize), Color.Red);
System.Diagnostics.Debug.WriteLine("textSize = " + (textSize).ToString());
// ----------------
// Set the TextRenderingHint property.
g_progressInfo.TextRenderingHint =
System.Drawing.Text.TextRenderingHint.AntiAlias;
// ... get the Size needed to accommodate the formatted text
Size preferredSize_progressInfo = g_progressInfo.MeasureString(
this.progressInfo.Text, this.progressInfo.Font).ToSize();
System.Diagnostics.Debug.WriteLine("preferredSize_progressInfo = " +
(preferredSize_progressInfo).ToString());
/*
g_progressInfo.MeasureString above calculates the size of the string as floting
point numbers that get truncated by .ToSize().
... pad the text by 1 pixel, and resize the label
*/
System.Diagnostics.Debug.WriteLine("this.progressInfo.ClientSize = " +
(this.progressInfo.ClientSize).ToString());
this.progressInfo.ClientSize = new Size(
preferredSize_progressInfo.Width + 10, preferredSize_progressInfo.Height + 1);
System.Diagnostics.Debug.WriteLine("this.progressInfo.ClientSize = " +
(this.progressInfo.ClientSize).ToString());
// ... clean up the Graphics object
g_progressInfo.Dispose();
}
Here is the output from debugging:
Result from TextRenderer ---> textSize = {Width=270, Height=13}
Size calculated by MeasureString() ---> preferredSize_progressInfo = {Width=260, Height=14}
Initial label client size ---> progressInfo.ClientSize = {Width=100, Height=23}
Resized client size based on MeasureString ---> this.progressInfo.ClientSize = {Width=270, Height=15}
The issue is that the string widths calculated differ by 10 pixels. As it turns out, the width calculated by the TextRenderer, width = 270, is correct and the one calculated by MeasureString, width = 260, is incorrect because it truncates the display of the input string to: "Reading data from input data file ... input". I have also tried measuring the string width using MeasureCharacterRanges() and this approach yields a result similar to that produced by the MeasureString approach. The size calculated by TextRenderer seems to display the text correctly.
Yes, I understand that if this is the case I should simply use the TextRenderer, but can someone please explain to me the source of such a huge discrepancy in the string width calculated by the various methods? Any help or guidance would be greatly appreciated. Thank you.