UserGuide

Updating Code That Used the Graphics Property

From Xojo Documentation

Prior to 2018r3 Window and Canvas both had a Graphics property that you could access and draw to. This was deprecated in 2011 because it had significant performance issues on all platforms. The preferred way to draw your graphics since 2011 has been to use the Window.Paint or Canvas.Paint event handlers and the supplied parameter g As Graphics.

Starting with 2018r3, this Graphics property was removed from Window and Canvas so if you had code that was still relying on it, that code will no longer compile. Here are some tips on how you can migrate your code to use the Paint event handlers and tell the Canvas to update with a call to Invalidate.

Simple Drawing

If your code was simple and just drawing a Picture to the Graphics property, then you would just move the code to the Paint event handler. For example, this code is drawing a picture:

Canvas1.Graphics.DrawPicture(MyPic, 0, 0)

Where that code existed, you would tell it to redraw Canvas1:

Canvas1.Invalidate(False)

And then in the Canvas.Paint event handler you would draw the picture:

g.DrawPicture(MyPic, 0, 0)

More Advanced Drawing

If your code was doing more advanced drawing to the Graphics property then you will need to do more substantial changes to your code. Since you ideally want to do all the drawing in the Paint event handler you may need to use a separate means to store what was being updated (such a properties or a class) and then in the Paint event handler use these values to do the drawing.

So say you had code in a MouseDown event that was drawing a point on the Canvas when the mouse was clicked like this:

Canvas1.Graphics.FillRect(X, Y, 5, 5)

You would now create properties to store the X and Y values from the MouseDown event:

LastClickX As Integer
LastClickY As Integer

In MouseDown you would now save the values to the properties and tell the Canvas to update when the mouse was clicked:

LastClickX = X
LastClickY = Y
Canvas1.Invalidate(False)

Lastly you would put code in Canvas.Paint to draw the point:

g.FillRect(LastClickX, LastClickY, 5, 5)

Although the above is recommended, you may find that making all the changes needed is more than you want to change. Another technique you can use is to do the drawing in an offscreen picture and then draw the picture in the Canvas. With this technique you create a Picture property for your drawing:

MyDrawing As Picture

You then initialize it to the size you want using the Window.BitmapForCaching method (so that it is HiDPI compatible):

MyDrawing = Self.BitmapForCaching(500, 500)

And then everywhere where you were drawing directly to Graphics you now draw to your Picture property and tell the Canvas to update. So instead of:

Canvas1.Graphics.ForeColor = RGB(255, 0, 0)
Canvas1.Graphics.DrawLine(0, 0, 100, 100)

your code would look like this:

MyDrawing.Graphics.ForeColor = RGB(255, 0, 0)
MyDrawing.Graphics.DrawLine(0, 0, 100, 100)
Canvas1.Invalidate(False)

And in the Paint event for Canvas1:

g.DrawPicture(MyDrawing, 0, 0)

See Also