I played with Graphics.MeasureString , but could not get accurate results. The following code gives me pretty consistent results with different font sizes with Graphics.MeasureCharacterRanges .
private Rectangle GetTextBounds(TextBox textBox, int startPosition, int length) { using (Graphics g = textBox.CreateGraphics()) { g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; CharacterRange[] characterRanges = { new CharacterRange(startPosition, length) }; StringFormat stringFormat = new StringFormat(StringFormat.GenericTypographic); stringFormat.SetMeasurableCharacterRanges(characterRanges); Region region = g.MeasureCharacterRanges(textBox.Text, textBox.Font, textBox.Bounds, stringFormat)[0]; Rectangle bounds = Rectangle.Round(region.GetBounds(g)); Point textOffset = textBox.GetPositionFromCharIndex(0); return new Rectangle(textBox.Margin.Left + bounds.Left + textOffset.X, textBox.Margin.Top + textBox.Location.Y + textOffset.Y, bounds.Width, bounds.Height); } }
This snippet simply places a panel on top of my TextBox to illustrate the computed rectangle.
... Rectangle r = GetTextBounds(textBox1, 2, 10); Panel panel = new Panel { Bounds = r, BorderStyle = BorderStyle.FixedSingle, }; this.Controls.Add(panel); panel.Show(); panel.BringToFront(); ...
source share