DrawString word wrap fails on Compact Framework

  • Thread starter Thread starter soerenbech
  • Start date Start date
S

soerenbech

I have designed a cusom control called ImageButton with an image and a
text. The text is drawn on the control with

Graphics.DrawString (String, Font, Brush, RectangleF, StringFormat)

the StringFormat (fmt) is setup to enable word-wrapping, horizontal and
vertical centering with

fmt.Alignment = StringAlignment.Center;
fmt.LineAlignment = StringAlignment.Center;

This works just great in design time, and when executed on the PC, but
in PPC2003SE (device or emulator) text is not word wrapped.

Any ideas ?

Søren B. Christensen
 
Here is a sample code I'm using and which is working:

SizeF textSize = g.MeasureString(
this.Text,
this.Font
);
float maxWidth = this.Width;
if(textSize.Width > maxWidth)
{
// textSize.Height *= ((textSize.Width / maxWidth) + 1);
// textSize.Height += (textSize.Width / maxWidth) * 2;
textSize.Height = 1000;
textSize.Width = maxWidth;
}

RectangleF labelRect = new RectangleF(0,0,0,0);
switch(this.TextAlign)
{
case ContentAlignment.TopLeft:
labelRect = new RectangleF(
this.Location.X,
this.Location.Y, // + (this.Height - textSize.Height) /2,
textSize.Width,
textSize.Height
);
break;
case ContentAlignment.TopCenter:
labelRect = new RectangleF(
this.Location.X + (this.Width - textSize.Width) / 2,
this.Location.Y, // + (this.Height - textSize.Height) /2,
textSize.Width,
textSize.Height
);
break;
case ContentAlignment.TopRight:
labelRect = new RectangleF(
this.Location.X + this.Width - textSize.Width - 3,
this.Location.Y, // + (this.Height - textSize.Height) /2,
textSize.Width,
textSize.Height
);
break;
}
g.DrawString(
this.Text,
this.Font,
new SolidBrush(this.ForeColor),
labelRect
);

You will have to adapt a little the code since I draw directly on the form
but the idea is to calculate the rectangle where the label will reside...

Steve

<[email protected]> a écrit dans le message de (e-mail address removed)...
I have designed a cusom control called ImageButton with an image and a
text. The text is drawn on the control with

Graphics.DrawString (String, Font, Brush, RectangleF, StringFormat)

the StringFormat (fmt) is setup to enable word-wrapping, horizontal and
vertical centering with

fmt.Alignment = StringAlignment.Center;
fmt.LineAlignment = StringAlignment.Center;

This works just great in design time, and when executed on the PC, but
in PPC2003SE (device or emulator) text is not word wrapped.

Any ideas ?

Søren B. Christensen
 
Thank you Steve,

I just discovered, that if I drop the vertical centering, it works on
CF too.
I need to decide if vertical centering is crucial for my app, if so I
have your solution ;o)

Does anyone know if this behavior is intentional or a "feature" of CF?

Søren B. Christensen
 
Vertical centering isn't supported in CE at the OS level.

-Chris

Thank you Steve,

I just discovered, that if I drop the vertical centering, it works on
CF too.
I need to decide if vertical centering is crucial for my app, if so I
have your solution ;o)

Does anyone know if this behavior is intentional or a "feature" of CF?

Søren B. Christensen
 
Well, Chris, according to the documentation, LineAlignment IS supported
in Compact Framework.
And it actually works, but it just disables word wrapping.

Søren
 
solution

// Draw the text if any

if (!String.IsNullOrEmpty(this.Text))

{

StringFormat stringFormat = new StringFormat();

stringFormat.Alignment = _textAlignH;

if (_textAlignV == StringAlignment.Center)

{

SizeF stringSize = gx.MeasureString(this.Text, this.Font);

if (stringSize.Width < this.Width)

{

// 1 line

stringFormat.LineAlignment = StringAlignment.Center;

}

else

{

// >=2 lines - manually align vertically

int iProbablyNLines = (int)Math.Ceiling((stringSize.Width + 1) / this.Width);

int iVertMargin = (int)((this.Height - iProbablyNLines * stringSize.Height) / 2);

if (iVertMargin < 0)

{

iVertMargin = 0;

}

rectangle =
new Rectangle(this.Bounds.X, this.Bounds.Y + iVertMargin, this.Bounds.Width - 1, this.Bounds.Height - 1 - 2 * iVertMargin);

}

}

Color textColor;

if (this.Enabled)

{

textColor =
this.ForeColor;

}

else

{

textColor =
SystemColors.GrayText;

}

gx.DrawString(
this.Text, this.Font, new SolidBrush(textColor), rectangle, stringFormat);

}

 
Here is a solution in VB:

'Draw a string in a rectangle (fixes bug in WinCE)
PrivateSub xDrawString(ByVal text AsString, ByVal font As Font, _
ByVal brush As SolidBrush, ByVal g As Graphics, _
ByVal rec As Rectangle, ByVal format As StringFormat)

If text.IndexOf(vbLf) > 0 Then
'Multi Line
'Make array of lines
Dim strArray() AsString
strArray = text.Split(vbLf)

'make a new rec the size of one line
Dim lineSize As SizeF = g.MeasureString(strArray(0), font)
Dim lineRec AsNew Rectangle
lineRec = rec
lineRec.Height = lineSize.Height

'Set the top of the first line
Dim firstLineTop AsInteger
SelectCase format.LineAlignment

Case StringAlignment.Near
firstLineTop = rec.Top

Case StringAlignment.Center
firstLineTop = (rec.Height / 2) - ((lineSize.Height * strArray.Length) / 2) + rec.Top

Case StringAlignment.Far
firstLineTop = (rec.Height) - (lineSize.Height * (strArray.Length)) + rec.Top
EndSelect

'Draw all lines
Dim i AsInteger
format.LineAlignment = StringAlignment.Near

For i = 0 To strArray.Length - 1
lineRec.Location = New Point(lineRec.Left, (lineSize.Height * i) + firstLineTop)
g.DrawString(strArray(i), font, brush, lineRec, format)
Next

Else
'One line
g.DrawString(text, font, brush, rec, format)
EndIf

EndSub
 
The above code splits the string at every vbLF., in to separate lines
What if each line was wider than the screen width.
While it measures the string nowhere the width of the string is checked.

This won't get the work done!
 
Text Wrap .net cf2 VB

[/URL]'''Returns Wrapped text string baed on given width
Dim XArraylist As New ArrayList
Public Function GetWrapTxt(ByVal Xstr As String, ByVal XWidth As Integer, ByVal XFont As Font, ByVal gr As graphics) As String
Dim stringSize As New SizeF
stringSize = gr.MeasureString(Xstr, XFont)
Dim strArray() As String = Xstr.Split(" ")
Dim ystr As String = ""
Dim ZStr As String = ""

Dim StartPos% = 0
Dim EndPos% = 1

If stringSize.Width > XWidth Then
Dim Xlength As Integer = Xstr.Length
For i% = 1 To (Xlength - 1)

ystr = Xstr.Substring(StartPos, EndPos)
stringSize = gr.MeasureString(ystr, XFont)
If stringSize.Width > XWidth Then
If ZStr = "" Then
ZStr = ystr
XArraylist.Add(ystr)
Else
ZStr = ZStr & vbCr & ystr
XArraylist.Add(ystr)
End If
StartPos = i
EndPos = 0
End If
EndPos = EndPos + 1
Next
If EndPos > 1 Then
XArraylist.Add(ystr)
ZStr = ZStr & vbCr & ystr
End If
Else
Return Xstr
End If

Return ZStr
End Function



Public Function TextWrap(ByVal Xstr As String, ByVal XWidth As Integer, ByVal XFont As Font, ByVal gr As graphics, Optional ByVal justify As Boolean = False) As String
Dim stringSize As New SizeF

stringSize = gr.MeasureString(Xstr, XFont)
If stringSize.Width <= XWidth Then Return Xstr

Dim strArray() As String = Xstr.Split(" ")
Dim StrLenArray(strArray.Length)
Dim TempStr As String = ""
Dim curstr As String = ""
Dim PrevStr As String = ""
Dim TempStr1 As String = ""


'1 Take the first string and check the width - call as PrevStr
PrevStr = strArray(0)
'2 check the width if PrevStr
stringSize = gr.MeasureString(PrevStr, XFont)
'3 if the width is more than xwidth then wrap it - Call it PrevStr
If stringSize.Width > XWidth Then PrevStr = GetWrapTxt(PrevStr, XWidth, XFont, gr)

If strArray.Length = 1 Then Return PrevStr

For i% = 1 To strArray.Length - 1
'4 go to next str and call it as CurStr
curstr = GetWrapTxt(strArray(i), XWidth, XFont, gr)
'5 take the CurStr and add it with the PrevStr with a space- call it TempStr
TempStr = PrevStr & " " & curstr
'6 check the width of tempStr
stringSize = gr.MeasureString(TempStr, XFont)
'7 if the width is more than xwidth then
'add prevStr + vbcr+ curstr - call it TempStr1

If stringSize.Width > XWidth Then
TempStr1 = PrevStr & vbCr & curstr
Else
TempStr1 = TempStr
End If

PrevStr = TempStr1

Next

Return PrevStr
'======================================================================

End Function


use the TextWrap function an supply the string.
It will return the wrapped text. use creategraphics,drawstring command to draw wrapped text on the screen.

I've attached a screen shot below
 

Attachments

  • textwrap Screenshot.webp
    textwrap Screenshot.webp
    23.8 KB · Views: 508
Last edited:
Back
Top