tags:

views:

220

answers:

3

Hi,

I am drawing a string on a big bounding box and using StringFormat to align the string appropriately. However I need the actual (X, Y) location of the string once it's drawn (not just the size given by MeasureString).

I'm using the code below:

CharacterRange[] ranges = { new CharacterRange(0, this.Text.Length) };
format.SetMeasurableCharacterRanges(ranges);

//Measure character range
Region[] region = g.MeasureCharacterRanges(this.Text, this.Font, layoutRect, format);
RectangleF boundsF = region[0].GetBounds(g);
bounds = new Rectangle((int)boundsF.Left, (int)boundsF.Top,
                       (int)boundsF.Width, (int)boundsF.Height);

It's a code segment so ignore any missing declarations. The point is that rectangle the code above gives is not the right size, the last character of the string is dropped and only the first line of strings are drawn.

Anyone know why, or perhaps a better way to go about this?

Thanks

+1  A: 

Use:

TextBox tb = new TextBox { Text = "Test", Multiline = true };
Size size = System.Windows.Forms.TextRenderer.MeasureText(tb.Text, tb.Font);
Point location = new Point( //Is this what you were looking for?
    tb.Location.X + size.Width, 
    tb.Location.Y + size.Height);

Note that there are additional overloads to this method, please check out.

Shimmy
Also, in DataGridViewCell if I remember well there are additional functions like this.
Shimmy
+2  A: 

Make sure you're using the right format for measuring your text. You haven't included the entire source code, so I can't tell if you are.

There are two 'standard' format values you can use: StringFormat.GenericTypographic and StringFormat.GenericDefault. If memory serves, the default one selected is typically GenericDefault, but the one you want when rendering UI is GenericTypographic.

Therefore, instead of doing new StringFormat(), you want to do StringFormat.GenericTypographic.Clone() instead. That should correct the margins/spacing and give you measurement results that match what you see rendered on the Graphics surface.

The strategy I typically use is to construct a single StringFormat instance and use it for both text rendering and measurement to ensure things line up - I avoid any method that lets me omit the StringFormat since the default probably isn't what I want.

Hope this helps. If you're still having trouble, try posting a more complete code snippet so we can see how you're painting your text.

Kevin Gadd
A: 

I am definitely using the same StringFormat object to measure and draw the text.

What I have ended up doing is I use the code above and then measure again with TextRenderer and adjust the size and location accordingly