Drawing a Rubber Band line in C#

We have an example project for C# that shows how to use the csXImage ActiveX control to draw a line at the position of the mouse cursor. It uses the technique known as "Rubber Banding" where the line is drawn temporarily and can be moved with the mouse until the button is released. Download the project code.

The demo uses the trial version of csXImage, which must must be registered on the development computer and the licence file must be in the same folder as the .ocx control. Running our installer will have performed the registration and unpacking of files.

Some global variables are used to record the start and end of the line and Boolean variables are needed to indicate whether the line is being drawn as the mouse moves.

Boolean drawLineStart, drawingLine;
int x1, y1, x2, y2;

When the form is loaded a blank image is drawn in the control to use in the demo, and the PenMode property is set to pmNotXor. This setting for the pen is what allows the line to be drawn and rubbed out again because it draws a line by inverting the pixels, rather than drawing a line of a specific colour.

private void fMain_Load(object sender, EventArgs e)
{
  axImageBox1.NewImage(360, 280);

  //This PenMode means that a line can be erased by re-drawing on top of it
  axImageBox1.PenMode = csXImageTrial.TxPenMode.pmNotXor;
}

The button that starts the line drawing process sets the drawLineStart Boolean variable to true. The button is then disabled until the line is finished.

private void cmdDrawLine_Click(object sender, EventArgs e)
{
  //This flag indicates to the OnMouseDownEvent that drawing will start
  drawLineStart = true;

  //Disable this button
  cmdDrawLine.Enabled = false;
}

The OnMouseDown event will be triggered regardless of whether the Draw Line button has been clicked so the value of the drawLineStart variable must be checked first. If a line is being drawn the coordinates are recorded. OnMouseDown provides the mouse coordinates as parameters. The drawingLine Boolean variable is set to be true for use by the OnMouseMove event.

private void axImageBox1_OnMouseDown(object sender,
    AxcsXImageTrial.IImageBoxEvents_OnMouseDownEvent e)
{
  if (drawLineStart)
  {
    //Record the start coordinates of the line
    x1 = e.x;
    y1 = e.y;
    x2 = e.x;
    y2 = e.y;

    //Reset the start flag
    drawLineStart = false;

    //This flag indicates to the OnMouseMove event that drawing is in progress
    drawingLine = true;
  }
}

OnMouseMove will be triggered whenever the mouse moves but action only needs to be taken when a line is being drawn. That is the purpose of the Boolean variables drawingLine and drawLineStart. When drawing is in progress the mouse cursor is changed to a cross hair.

When drawLine is true the old line must be erased by drawing over it using the pmNotXor setting for PenMode. The start and previous end point coordinates have been stored previously. After deleting the old line the new end point coordinates are set and a new line is drawn.

private void axImageBox1_OnMouseMove(object sender,
    AxcsXImageTrial.IImageBoxEvents_OnMouseMoveEvent e)
{
  if (drawingLine || drawLineStart)
    //Use the crosshair cursor when drawing
    fMain.ActiveForm.Cursor = Cursors.Cross;
  if (drawingLine)
  {
    //Erase the previous line
    //(note the PenMode setting in fMain_Load)
    axImageBox1.DrawLine(x1, y1, x2, y2);

    //Set the new line end coordinates and draw a new line
    x2 = e.x;
    y2 = e.y;
    axImageBox1.DrawLine(x1, y1, x2, y2);
  }
}

Finally, the drawing is stopped when the mouse button is released. The cursor is changed back to the default and the Draw Line button is enabled.

private void axImageBox1_OnMouseUp(object sender,
    AxcsXImageTrial.IImageBoxEvents_OnMouseUpEvent e)
{
  //Stop drawing and re-enable the Draw button
  drawingLine = false;
  cmdDrawLine.Enabled = true;
  fMain.ActiveForm.Cursor = Cursors.Default;
}