I have panel that I have customized. I use it to display text. But sometimes that text is too long and wraps to the next line. Is there some way I can auto resize the panel to show all the text?
I am using C# and Visual Studio 2008 and the compact framework.
Here is the code I am wanting to adjust the size for:
(Note: HintBox is my own class that inherits from panel. So I can modify it as needed.)
public void DataItemClicked(ShipmentData shipmentData)
{
// Setup the HintBox
if (_dataItemHintBox == null)
_dataItemHintBox = HintBox.GetHintBox(ShipmentForm.AsAnObjectThatCanOwn(),
_dataShipSelectedPoint,
new Size(135, 50), shipmentData.LongDesc,
Color.LightSteelBlue);
_dataItemHintBox.Location = new Point(_dataShipSelectedPoint.X - 100,
_dataShipSelectedPoint.Y - 50);
_dataItemHintBox.MessageText = shipmentData.LongDesc;
// It would be nice to set the size right here
_dataItemHintBox.Size = _dataItemHintBox.MethodToResizeTheHeightToShowTheWholeString()
_dataItemHintBox.Show();
}
I am going to give the answer to Will Marcouiller because his code example was the closest to what I needed (and looks like it will work). However, this is what I think I will use:
public static class CFMeasureString
{
private struct Rect
{
public readonly int Left, Top, Right, Bottom;
public Rect(Rectangle r)
{
this.Left = r.Left;
this.Top = r.Top;
this.Bottom = r.Bottom;
this.Right = r.Right;
}
}
[DllImport("coredll.dll")]
static extern int DrawText(IntPtr hdc, string lpStr, int nCount,
ref Rect lpRect, int wFormat);
private const int DT_CALCRECT = 0x00000400;
private const int DT_WORDBREAK = 0x00000010;
private const int DT_EDITCONTROL = 0x00002000;
static public Size MeasureString(this Graphics gr, string text, Rectangle rect,
bool textboxControl)
{
Rect bounds = new Rect(rect);
IntPtr hdc = gr.GetHdc();
int flags = DT_CALCRECT | DT_WORDBREAK;
if (textboxControl) flags |= DT_EDITCONTROL;
DrawText(hdc, text, text.Length, ref bounds, flags);
gr.ReleaseHdc(hdc);
return new Size(bounds.Right - bounds.Left, bounds.Bottom - bounds.Top +
(textboxControl ? 6 : 0));
}
}
This uses the os level call to draw text. By P-Invoking it I can get the functionality I need (multi line wrapping). Note that this method does not include any margins. Just the actual space taken up by the text.
I did not write this code. I got it from http://www.mobilepractices.com/2007/12/multi-line-graphicsmeasurestring.html. That blog post had my exact problem and this fix. (Though I did make a minor tweak to make it a extension method.)
You could use the
Graphics.MeasureString()method.With a code sample of your text assignment onto your panel, I could perhaps provide a code sample using the
MeasureString()method, if you need it.I have no way to know whether the
Graphics.MeasureString()method is part of the Compact Framework, as it is not said on the page I linked.EDIT #1
Here’s a link where I answered to another text-size related question, while I look for writing a sample for you. =)
EDIT #2
Here’s another link related to your question. (Next edit is the sample code. =P)
EDIT #3
Disclaimer: This code has not been tested and is off the top of my head. Some changes might be obligatory in order for you to test it. This provides a guideline to achieve what you seem to want to accomplish. There might be a better way to do this, but I know this one works. Well, the algorithm works, as you can see in my other answers.
Instead of the line:
You could as well do the following:
Because
Font.Sizeproperty is readonly. So, you need to create a new instance of theSystem.Drawing.Fontclass each time theFont.Sizeshall change.In your comparison, instead of having the line:
you could also have:
This would nullify the need for a second
Fontclass instance, that is f.Please feel free to post feedbacks as I could change my sample to fit your reality upon the feedbacks received, so that it better helps you. =)
I hope this helps! =)