Click here to Skip to main content
Click here to Skip to main content

YaWhiteBoard - A Simple Whiteboard using C#

, 14 Mar 2012
Rate this:
Please Sign up or sign in to vote.
A simple Whiteboard application
yaWhiteboard - Yet another whiteboard application

Creating Our Own Types

We know that the whiteboard application will have two modes, i.e., Write mode and Erase mode so we go ahead and create an enum to keep track of the current mode.

enum MODE
{
    WRITE,
    ERASE
};

Now the way we are going to achieve the drawing functionality is:

  1. Get the position where user clicked the mouse down (say point1)
  2. Check for mouse movement
  3. If mouse is moved, then get the new mouse position (say point2)
  4. Draw a line from point1 to point2
  5. Now this new position will become the old position because user will eventually move the mouse further (i.e., point1 = point2)
  6. Keep doing all the above steps till user releases the mouse.

So we now create a small struct for holding the Line data:

struct Line
{
    public Pen pen;
    public Point p1;
    public Point p2;

    public Line(Pen p, Point one, Point two)
    {
        pen = p;
        p1 = one;
        p2 = two;
    }
}

This Line keeps track of the terminal points of the line and the Pen which was used to draw this line (since Pen contains Color & Width information for the Line).

Tracking the Mouse Down and Up Events

The way we do this is to have a member variable to remember the state and handing the Mouse_down and Mouse_Up Events of the SplitContainers's Panel. Also since we are planning to keep track of mouse position when the mouse is pressed or released, we need to keep track of the mouse position too in these events.

bool isPressed = false;
//these are X n Y coordinates of point1 in our algorithm
int x1;
int y1;

private void splitContainer1_Panel2_MouseUp(object sender, MouseEventArgs e)
{
    x1 = e.X;
    y1 = e.Y;

    isPressed = false;
}

private void splitContainer1_Panel2_MouseDown(object sender, MouseEventArgs e)
{
    x1 = e.X;
    y1 = e.Y;

    isPressed = true;
}

Now when the mouse is moved, we need to draw the line and update the points which will be done in Mouse_Move event.

//These coordinates are for "point2" of our algorithm
int x2;
int y2;

private void splitContainer1_Panel2_MouseMove(object sender, MouseEventArgs e)
{
    if (isPressed == true)
    {
        x2 = e.X;
        y2 = e.Y;

        Line line = new Line(CurrentPen, new Point(x1, y1), new Point(x2, y2));
        g.DrawLine(line.pen, line.p1, line.p2);

        x1 = x2;
        y1 = y2;
    }
}

The code above shows CurrentPen is being to draw the line. This variable will actually be updated based on users selection of markers. If the user selects a marker, it will return a marker of appropriate color and if user selects eraser, it will return a Pen of white color (effectively an eraser). The implementation details are shown below. (Refer to the source code for details.)

pen = new Pen(Color.Blue, 2.0f);
eraser = new Pen(Color.White, 100.0f);

private Color CurrentColor
{
    get { return pen.Color; }
    set { pen.Color = value; }
}

private Pen CurrentPen
{
    get
    {
        if (mode == MODE.WRITE)
        {
            return pen;
        }
        else
        {
            return eraser;
        }
    }
}

The Problem

We are now almost done with the main functionality as we are drawing on the board with either marker or eraser. But there is a small problem. The problem is when our application goes out of focus, i.e., if user minimizes it or does an alt-tab, the drawings on our board will go away. To persist the drawing in such conditions, we need to:

  1. Remember the drawings on the board (this will change our Mouse_Move method)
  2. Override the Paint method and redraw everything in it.

So let us have a list that keeps track of whatever we drew so far.

List<Line> lines = null;

private void splitContainer1_Panel2_MouseMove(object sender, MouseEventArgs e)
{
    if (isPressed == true)
    {
        x2 = e.X;
        y2 = e.Y;

        Line line = new Line(CurrentPen, new Point(x1, y1), new Point(x2, y2));
        g.DrawLine(line.pen, line.p1, line.p2);

        lines.Add(line);  //this will help to remember all the lines we drew so far

        x1 = x2;
        y1 = y2;
    }
}

And then, we just have to redraw everything in the overridden Paint method.

private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;

    foreach (Line l in lines)
    {
        g.DrawLine(l.pen, l.p1, l.p2);
    }
}

And that's it, we have a rudimentary implementation of whiteboard in place. This is not the most elegant way to do it, but it is one way to do it.

History

  • 08 Feb 2012: First implementation of a rudimentary white board
  • 09 Feb 2012: Updated to use all colors and choose custom marker size (as suggested in the comments)
  • 10 Feb 2012: Minor changes in user interface, removed the annoying radio button.
  • 14 Mar 2012: Fixed the bug where drawing colors are getting changed on repaint.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Rahul Rajat Singh
Software Developer (Senior)
India India
I Started my Programming career with C++. Later got a chance to develop Windows Form applications using C#. Currently using C#, ASP.NET & ASP.NET MVC to create Information Systems, e-commerce/e-governance Portals and Data driven websites.

My interests involves Programming, Website development and Learning/Teaching subjects related to Computer Science/Information Systems. IMO, C# is the best programming language and I love working with C# and other Microsoft Technologies.
  • Microsoft Certified Technology Specialist (MCTS): Web Applications Development with Microsoft .NET Framework 4
  • Microsoft Certified Technology Specialist (MCTS): Windows Communication Foundation Development with Microsoft .NET Framework 4
 
If you like my articles, please visit my website for more: www.rahulrajatsingh.com[^]
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
Questionbug Pinmemberwangxj_nemo11-Jan-13 1:28 
SuggestionAdd Save option Pinmemberradar_ksa19-Mar-12 3:13 
QuestionNot Bad PinmemberBassam Abdul-Baki8-Feb-12 4:45 
AnswerRe: Not Bad PinmemberRahul Rajat Singh9-Feb-12 7:17 
GeneralRe: Not Bad PinmemberBassam Abdul-Baki9-Feb-12 7:27 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140718.1 | Last Updated 14 Mar 2012
Article Copyright 2012 by Rahul Rajat Singh
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid