Hi everyone,
several days ago i was moving from Xojo release 2019 1.1 to the latest release.
In one of my projects everything seems to work fine in the new release but i’ve got one problem with canvases.
In each window I’m displaying a title painted on a canvas and a ‘NEU’-button, a canvas as well. In the older release it was displayed correctly like this:
The same code in the latest release shows the canvas like this:
But when i activate the window with the canvas a second thime everything ist displayed correctly.
Here is my code in the paint event of the ‘title’-canvas:
Dim s As String
s=“Aufträge”
If len(s)>0 Then
g.DrawString(s,0,(g.Height/2)+(g.TextAscent/2)-2)
End If
Me.Width=g.StringWidth(s)+5
Me.Invalidate
canPlus.Left=Me.Left+Me.Width+10
canPlus.invalidate
I tried in other releases newer than 2019 1.1 as well, having the same problems.
Do i have to do something different with displaying canvases in the newer releases?
First off i think it may be better to remove the (me.)invalidate inside the paint event, it will cause a redraw loop probably.
You might want to check the new API 2.0 functions and move to those, so g.DrawString becomes g.DrawText etc. These are probably more tested in xojo 2021+ versions.
g.DrawingColor = StyleApp.titleColor
g.FontName = StyleApp.titleFont // Set to the font name as string
g.FontSize = StyleApp.titleSize
Dim s As String = "Aufträge"
If len(s)>0 Then
g.DrawText(s,0,(g.Height/2)+(g.FontAscent/2)-2)
End If
Me.Width=g.TextWidth(s)+5
Me.Invalidate // <-- are you sure this is needed in the paint event?
canPlus.Left=Me.Left+Me.Width+10
canPlus.invalidate
Thanks Derk,
i just updated to the new API 2.0 functions but still have the same problem. I also tried it with me.invalidate inside the Paint event and without the invalidate. The buttons and titles are only displayed correctly when i refresh the window e. g. resize or reactivate.
Remove this code from the Paint event and calculate the values outside the event/before the event is fired. Paint is for drawing only. Never invalidate here.
Carsten, this may be a solution, but how can i calculate the width of the string which is inside the paint event from the outside? This button needs a variable string because im displaying it with different content depending on the language and other parameters.
It is strange to draw in the canvas and change its size after.
By doing that, if the size is increased, you have to wait the next refresh to have the right drawing.
Create a temp picture 1 x 1 pixels and use it’s Graphics with the same values (font name, size etc.) to calculate string width and others. Store these values in properties and set the size and position of the canvases. Use the properties also in the Paint event.
Dim s as String = “Very_very_long_string”
System.DebugLog(Me.Width.ToText) //=> 60 the first time
Me.Width = g.TextWidth(s)+5
System.DebugLog(Me.Width.ToText) //=> 125
g.DrawText(s, 0, (g.Height/2)+(g.FontAscent/2)-2)
The text is not displayed correctly.
In the action event of the button :
Canvas1.Invalidate
A click on the button and the text is displayed correctly.
Canvas1.Invalidate in the Activate event of the window solves also the problem.
Absolutely. When you change the Canvas’s size during the paint event, you are invalidating it by that. Move all resizing and invalidating out of the paint event.