Click here to Skip to main content
15,123,118 members
Articles / Programming Languages / C#
Posted 27 Feb 2004


117 bookmarked

Canvas implementation for C#

Rate me:
Please Sign up or sign in to vote.
4.33/5 (28 votes)
21 Mar 20044 min read
Design and implementation of canvas in C#

Image 1


In many different applications, graphical input is needed. Along with creating new graphical objects such as lines, rectangles and polygons, objects editing and viewing in different scale are required. In some cases, graphics events such as shape creation, selection and moving should be bound to some application logic.

Canvas or graphical editor is a component that provides an application with such functionality.


Canvas control or widget is a component containing different types of graphical objects responsible for its viewing and editing.

Most of the GUI toolkits have their own canvas components. For example, there are canvases in Qt toolkit, Borland C++ Builder and Tcl/Tk. Somehow, it’s missing in .NET.

For canvas implementation and functionality, I use my experience with Qt and Tcl/Tk toolkits. In both toolkits, canvas provides rich functionality to create and manipulate graphical objects.

In both toolkits, scaling and translating of canvas affects geometry of graphical objects stored inside. It’s inconvenient when you're storing “real world“ measurements in your canvas, so each time you edit it in the canvas, you should keep track on changes of the “real world” coordinate system.

To avoid this inconvenience, this implementation is logically divided to geometrical model and view. When you're editing objects inside the canvas, geometrical model (presented in “real world” coordinates) is changing and the view (client coordinates) stays the same, and when you rescale and scroll the canvas, the geometrical model stays unchanged.

Canvas geometrical model could have several views showing different parts of the model. All views are updated automatically when the model changes, it means that if you moving or editing shape in one of the views you will see changes in others.

Using canvas

Canvas is implemented in Canvas.cs file in CanvasControl namespace.

Example how to use it is in CanvasDemo.cs file.

To create a new Canvas and connect to its events:

// create new canvas
canvas1 = new CanvasControl.Canvas();
// connect listeners to canvas events
canvas1.CoordChangeEvent += new
canvas1.ItemNewEvent += new
canvas1.ItemEnterEvent += new


CoordChangeEvent event is generated when cursor moves inside the Canvas. A second parameter of the event handler CoordChangeEventHandler contains coordinates of the cursor and R,G,B values of the background image.

public void OnCoordChainged(object sender, 
CanvasControl.CoordEventArgs e)
    textBox1.Text = e.X.ToString() + "," + e.Y.ToString();

ItemNewEvent and ItemEnterEvent – events are generated when cursor enters and leaves graphical object. The second parameter contains ID (index) of the object. Graphical object could be accessed by its ID.

public void OnEnterCanvasItem(object sender, 
CanvasControl.ItemEventArgs e)
    textBox3.Text = e.indx.ToString();

In order to create additional view of existing Canvas (its geometrical model) we should create second Canvas, say canvas2 and attach it to previous one:

canvas2 = new CanvasControl.Canvas();

Canvas itself does not contain other graphical controls, it’s controlled by its API. But there is an option to connect Scrollbar controls to update scrollbars controls during canvas navigation.


To create, move or select graphical objects, we need to change Canvas state as follows:

// create graphical objects



// move objects
// select objects

Graphical object could be accessed by its ID and geometrical and other properties could be retrieved or updated. In the function bellow, ID-s of selected items are retrieved and updated with user defined color.

private void btnColor_Click(object sender, System.EventArgs 
        ColorDialog colorDialog = new ColorDialog();
        if(colorDialog.ShowDialog() != DialogResult.OK)

        Color color = colorDialog.Color;
        int [] selected = canvas1.GetSelected();
        foreach(int i in selected)
                 CanvasControl.CanvasItem item = canvas1.GetItem(i);
                 item.Icolor = color;


You can create your own geometrical object, to do it, you should implement CanvasItem interface (see Canvas.cs file) and use Canvas.AddShape method to put it into the canvas.

Design issues

Several design patterns are used in the design of the canvas.

Template pattern is used in CanvasItem class to implement some shapes common functionality in the base class.

Observer pattern is used to notify subscribers about canvas changes, it's implemented using C# events.

Facade pattern is used to hide internal canvas objects from the user.

Image 2

In the class diagram above classes creating canvas contol are presented

  • Canvas - encapsulates view of the canvas control (Model/View pattern). Canvas is syncronized with geometrical model CanvasGeomModelvia C# events. Every time the model had changed the model generates ItemChangedEvent or ModelChangedEvent forcing canvas update the view. Each time the view Canvas needs to display the model, it calls draw method of CanvasGeomModel specifying graphical context (or painter object) Graphics and a Matrix transformaion between "client" coordinate system of view and "real world" coordinate system of the model. Eventually from CanvasGeomModel draw request is delegated to concreat shapes, which implement CanvasItem draw interface to draw itself on the view.
  • CanvasGeomModel - encapsulates geometrical model of the canvas control. It is responsable for storing, editing and displaying of different shapes, derived from CanvasItem class. Geometrical objects are represented in the model in "real world" coordinates independently from "client" coordinates of different views.
  • CanvasItem - encapsulates common behavior of geometrical objects or shapes stored in geometrical model CanvasGeomModel. It represents interface using by Canvas to manipulate and display differents types of shapes. In order to create new shape one should implement methods defined in CanvasItem interface.
    public class LineCanvasItem : CanvasItem
      public float x1;
      public float y1;
      public float x2;
      public float y2;
      private bool is_selected = false;
      // construct from 2 points coordinates
      public LineCanvasItem(float x_1,float y_1,float x_2,float y_2)
        x1 = x_1;
        y1 = y_1;
        x2 = x_2;
        y2 = y_2;
      // returns true if item is selected
      public override bool isSelected()
        return is_selected;
      // select item
      public override void select(bool m)
        is_selected = m;
      // returns true if the item is within the distanse
      public override bool isCloseToPoint(PointF pnt,float dist)
        double curr_dist = Geom.segmentToPointSqrDist(
          new PointF(x1,y1),new PointF(x2,y2),pnt);
        return Math.Sqrt(curr_dist) < dist;
      // return bounding box of the item
      public override RectangleF boundingBox()
        return new RectangleF(x1,y1,x2-x1,y2-y1);
      // start point X coordinate of the shape
      public override float X()
        return x1;
      // start point Y coordinate of the shape
      public override float Y()
        return y1;
      // move shape to specified location
      public override void move(PointF p)
        float dx = p.X-x1;
        float dy = p.Y-y1;
        x1 += dx;
        y1 += dy;
        x2 += dx;
        y2 += dy;
      // move shape by specified shift
      public override void moveBy(float xs,float ys)
      // draw shape on the view
      public override void draw(Graphics graph,
          System.Drawing.Drawing2D.Matrix trans)
        // transform points to "client" view coordinate system
        PointF [] points = {new PointF(x1,y1), new PointF(x2,y2)};
        // draw line in "client" coordinate system
          graph.DrawLine(new Pen(Color.Cyan),
          graph.DrawLine(new Pen(Icolor),(int)points[0].X,
    Then Canvas.AddShape method should be used to add new shape to the canvas:
    canvas1.AddShape(new LineCanvasItem(10,10,100,100));
  • Geom - Geometrical procedures used in Canvas.


  • 28/02/2004 Initial version.
  • 17/03/2004 Geometrical model separated from canvas view + design explanations.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Eduard Baranovsky
Web Developer
Canada Canada
Baranovsky Eduard has been a software developer for more then 10 years. He has an experence in image processing, computer graphics and distributed systems design.

Comments and Discussions

QuestionSave drawing state (Polygon) C# Pin
Member 1362841421-Mar-18 9:31
MemberMember 1362841421-Mar-18 9:31 
QuestionExport as PNG image Pin
iamPaGe21-Feb-16 17:35
MemberiamPaGe21-Feb-16 17:35 
AnswerRe: Export as PNG image Pin
Luong Bang11-Jul-21 19:20
MemberLuong Bang11-Jul-21 19:20 
QuestionSave canvas with drawing Pin
SukirtiShetty1-Mar-14 1:53
MemberSukirtiShetty1-Mar-14 1:53 
AnswerRe: Save canvas with drawing Pin
Luong Bang11-Jul-21 19:13
MemberLuong Bang11-Jul-21 19:13 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey26-Feb-12 22:39
professionalManoj Kumar Choubey26-Feb-12 22:39 
Generaldraw line between 2 points GDAL Pin
Thabet Tech17-Jun-09 5:13
MemberThabet Tech17-Jun-09 5:13 
QuestionDocumentation Pin
gilles berbey25-Oct-07 13:02
Membergilles berbey25-Oct-07 13:02 
GeneralNeeds zoom to region Pin
Thomas West6-Apr-05 11:50
MemberThomas West6-Apr-05 11:50 
GeneralScrollbars and scrolling Pin
Thomas West5-Apr-05 15:48
MemberThomas West5-Apr-05 15:48 
GeneralRe: Scrollbars and scrolling Pin
jamesyla16-Sep-09 19:56
Memberjamesyla16-Sep-09 19:56 
Hello, i have the same issue regarding the Scroll bars.
have you found any solution?
pls reply me.
GeneralException throw in designer Pin
Karim Shehadeh9-Nov-04 16:31
MemberKarim Shehadeh9-Nov-04 16:31 
GeneralRe: Exception throw in designer Pin
Eduard Baranovsky10-Nov-04 8:27
MemberEduard Baranovsky10-Nov-04 8:27 
GeneralRe: Exception throw in designer Pin
Karim Shehadeh10-Nov-04 8:40
MemberKarim Shehadeh10-Nov-04 8:40 
QuestionRe: Exception throw in designer Pin
Ariel Vargas4-May-06 10:39
MemberAriel Vargas4-May-06 10:39 
AnswerRe: Exception throw in designer Pin
Eduard Baranovsky10-May-06 8:57
MemberEduard Baranovsky10-May-06 8:57 
GeneralMoveTo on Map Pin
Thomas West5-Oct-04 15:09
MemberThomas West5-Oct-04 15:09 
GeneralIs there any way we can save Canvas information to a database Pin
Thomas Ushus18-Sep-04 2:09
MemberThomas Ushus18-Sep-04 2:09 
GeneralRe: Is there any way we can save Canvas information to a database Pin
Eduard Baranovsky24-Sep-04 3:59
MemberEduard Baranovsky24-Sep-04 3:59 
GeneralText selectable &amp; Arc implementation Pin
pxp13-Aug-04 15:08
Memberpxp13-Aug-04 15:08 
GeneralRe: Text selectable &amp; Arc implementation Pin
Eduard Baranovsky18-Aug-04 4:01
MemberEduard Baranovsky18-Aug-04 4:01 
GeneralRe: Text selectable &amp; Arc implementation Pin
pxp18-Aug-04 4:14
Memberpxp18-Aug-04 4:14 
GeneralRe: Text selectable &amp; Arc implementation Pin
Eduard Baranovsky19-Aug-04 4:57
MemberEduard Baranovsky19-Aug-04 4:57 
GeneralRe: Text selectable &amp; Arc implementation Pin
pxp19-Aug-04 13:42
Memberpxp19-Aug-04 13:42 
QuestionText on this Canvas? Pin
Clinton Pierce23-Apr-04 9:20
MemberClinton Pierce23-Apr-04 9:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.