The Canvas control is a great way to draw pretty much anything to a window. With a Canvas, do all your drawing in its Paint event handler for the best quality and performance.
I’ve had many people ask for an example for how to create a Canvas that allows you to:
- Draw pictures within it (as objects)
- Move these objects
- Remove them
- Add labels to them
- Programmatically select one
This example demonstrates how to do all these things. It has a large Canvas on the window with several buttons that let you add and manage the objects on the Canvas.
Use the SegmentControl to select the type of object you want to add to the Canvas and click the Add Object button. You can optionally specify text to label the object using the field below the button.
Add as many objects as you want. You can click to select an object and it will have a black border drawn around it. You can drag any object within the Canvas.
The other buttons center or remove a selected object. You can use the Select Object # button to select the object number you specify (objects are numbered starting at 0).
About the Project
The concept is pretty simple. Essentially you have a class that represents objects to draw on the Canvas and that knows how to draw itself on a Canvas.
In this project, the CanvasObject class represents an object to draw on the Canvas. It contains everything it needs to know to draw itself, such as its coordinates, label text, the icon to display and other properties.
The ObjectContainerCanvas class is a subclass of Canvas that is responsible for all the drawing, moving and removing of CanvasObjects. This class has an array of CanvasObjects that it knows about. The objects in this array are drawn by the Canvas Paint event handler when appropriate by calling the Draw method on the object itself.
To allow you to drag an object within the Canvas, the MouseDrag event handler is used. It knows what the currently selected CanvasObject is and as you drag the mouse, it updates the coordinates for the CanvasObject.
When the Canvas is told to update itself, usually through a call to Invalidate, the Paint event is called. Here each CanvasObject in the array is drawn on the screen. This is the Paint event:
If Background <> Nil Then g.DrawPicture(Background, 0, 0) End If For Each co As CanvasObject In mCanvasObjects co.Draw(g) Next
The CanvasObject’s Draw method draws itself at its coordinates and also draws a selection rectangle around itself if it is selected. This is the Draw method:
// Draws the object on the canvas. g.DrawPicture(Image, Left, Top) If Selected Then Const kBorder = 2 // Draw selection rectangel around the image g.PenHeight = kBorder g.PenWidth = kBorder g.ForeColor = TextColor g.DrawRect(Left - kBorder, Top - kBorder, Width + kBorder * 2, Height + kBorder * 2) End If
In addition, ObjectContainerCanvas has two events that are called when an object is selected (ObjectSelected) and when an object is moved (ObjectMoved).
Check out the other methods on ObjectContainerCanvas that are used to add, move, remove and select objects. I hope you find this technique useful in your projects.