Drawing Canvas Backdrop

Having a great first day of tinkering! I have an event in a canvas to draw a portion of the associated backdrop graphic from the paint event. It’s working as I expect it to, however it is ALSO drawing the entire canvas backdrop behind it (as if is drawing the backdrop, then my paint logic on top). How do I get it to not draw the original backdrop, but only that from my logic in the paint event?


If there is nothing in the Paint event that draws the background, then it could be transparency. In the Open event of the canvas write:

Me.Transparent = True
Me.Backdrop= Nil

If this is not the reason, we would need to see what is written in the Paint event

So just to clarify…

you’ve got a picture assigned to the background of the window and you’ve placed a canvas on top and are drawing the picture there as well?

You can either assign an image to the Backdrop property of the canvas or you can draw an image (or a portion of one) in the Paint event. You usually don’t do both.

That is exactly what is happening.

1 Like

Gotcha. Alright, so this is what I’m trying - should be logical enough.

I have a button which can load a backdrop to Canvas1. That works. I want to draw a part of that canvas in my WorkArea canvas. Originally I was loading the image to both canvases and trying to draw part of it in the WorkArea. I’ve since stopped assigning anything to WorkArea’s backdrop (so it should be nil), and am just trying to draw a picture to it instead, grabbing the Picture that is loaded into Canvas1’s backdrop.

if Canvas1.Backdrop <> nil Then
  g.DrawPicture(Canvas1.Backdrop, 0, 0, 24, 24, 0, 0, 8, 8)
End if

Seems simple enough, but right now this draws nothing. Thoughts?

Are you sure there are any pixels in that small of a space?

Yep. It’s 100% full with either red, green, or blue. Trying to get an 8px section to show up in the work area.

I created a property for the window - workAreaImage, set as a Picture.

I’ve tried this. In my picker too:

Var myPic As Picture
Var myFile As FolderItem
Var d As OpenFileDialog
d = New OpenFileDialog
myFile = d.ShowModal
If myFile <> Nil Then
  myPic = Picture.Open(myFile)
  If myPic <> Nil Then
    workAreaImage = myPic
    Canvas1.Backdrop = myPic
  End If
End If

Then, in Canvas1:

if me.Backdrop <> nil Then
  g.DrawPicture(me.Backdrop, 0, 0, me.Width, me.Height, 0, 0, me.Backdrop.Width, me.Backdrop.Height)

That works as expected.

In WorkArea, I have this in the paint event:

g.DrawPicture(workAreaImage, 0, 0)

Just to keep it simple and see if I can get it to draw something. At this point, the WorkArea canvas never draws anything.

Don’t use the backdrop and the paint event. You’re just wasting cpu cycles that way.

This is completely unnecessary, as Greg pointed out. That said, it all works fine here. We need more information. Can you reproduce the problem in a fresh project? Are you calling canvas refresh or invalidate anywhere?

From xojo’s documentation (I didn’t understand if you do something like this):

You should not assign a new picture to the backdrop of the control when being inside the Paint event of that control. This can lead into problems like the backdrop not being painted.

I don’t understand why it is necessary to assign a bakdrop if the image is then drawn with g.DrawPicture
It would suffice to store the image in a Picture variable that is drawn directly with g.DrawPicture if it is <> Nil

Sorry, maybe this is confusing.

There are TWO canvases. There is a picker canvas, and a workspace canvas. The picker canvas allows you to load up a graphic and pick a section of it to work with. The workspace allows you to stamp that section.

When you click the button, you load the image file to both the picker canvas and identify the image to use in the workspace canvas.

The reason I was doing both with the picker canvas is because I it to be scaled. Not using DrawPicture in the picker canvas and just giving it a backdrop assignment results in it being drawn at 1:1 scale.

I just tried both canvases NOT having any backdrop image ever set, and both trying to read from workAreaImage, which is now set by the button. However, nothing gets drawn in either place now.

Again, try to replicate it in a simple project. It works fine for me.

1 Like

This is the way. Backdrop is rarely useful.

1 Like

The solution was extremely simple. There was nothing wrong with my original code of trying to do this with images (as also suggested here), I just had to also force a refresh of both canvases upon loading that graphic. Now it works fine. Just one of those funky corners resulting from not knowing the right questions to ask. I’m sure I’ll have a few more today.

Thanks so much for the quick response. It helps :slight_smile:

1 Like