Archives for: October 2006, 13

13/10/06

Permalink 07:22:24 pm
Categories: General, Programming, .NET

Drawing a selection rubber band, take 3

In two previous posts (here and here) I have previously posted about how to draw rubber band selection rectangles similar to what Explorer does. Now a reader contacted me by email and asked for an extension: he wants to have a reverse selection, similar to this picture:

So, no problem of course :-) I started out from the improved version of the first demo and made a few changes – all you have to do is replace the SelectionPanel.OnPaint() method with this:

  protected override void OnPaint(PaintEventArgs e) {
    ColorMatrix colorMatrix = new ColorMatrix(new float[][] { 
      new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
      new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
      new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
      new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f},
      new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
    });

    ImageAttributes imageAttributes = new ImageAttributes( );
    imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
    Point[] destPoints = new Point[] {
      new Point(ClientRectangle.Left, ClientRectangle.Top),
      new Point(ClientRectangle.Right, ClientRectangle.Top),
      new Point(ClientRectangle.Left, ClientRectangle.Bottom)
    };
    e.Graphics.DrawImage(backgroundBitmap, destPoints, usableRect, GraphicsUnit.Pixel, imageAttributes);

    if (mouseDownPos != Point.Empty) {
      Point mousePos = PointToClient(MousePosition);
      Rectangle selectedRect = new Rectangle(
        Math.Min(mouseDownPos.X, mousePos.X),
        Math.Min(mouseDownPos.Y, mousePos.Y),
        Math.Abs(mousePos.X - mouseDownPos.X),
        Math.Abs(mousePos.Y - mouseDownPos.Y));

      Point srcRectLocation = selectedRect.Location;
      srcRectLocation.Offset(usableRect.Location);
      Rectangle srcRect = new Rectangle(srcRectLocation, selectedRect.Size);
      e.Graphics.DrawImage(backgroundBitmap, selectedRect, srcRect, GraphicsUnit.Pixel);

      using (Pen pen = new Pen(Color.Black)) {
        pen.DashPattern = new float[] { 2f, 2f };
        int thirdOfHeight = selectedRect.Height / 3;
        int thirdOfWidth = selectedRect.Width / 3;
        e.Graphics.DrawRectangle(Pens.White, selectedRect);
        e.Graphics.DrawLine(Pens.White, selectedRect.Left, selectedRect.Top + thirdOfHeight, selectedRect.Right, selectedRect.Top + thirdOfHeight);
        e.Graphics.DrawLine(Pens.White, selectedRect.Left, selectedRect.Bottom - thirdOfHeight, selectedRect.Right, selectedRect.Bottom - thirdOfHeight);
        e.Graphics.DrawLine(Pens.White, selectedRect.Left + thirdOfWidth, selectedRect.Top, selectedRect.Left + thirdOfWidth, selectedRect.Bottom);
        e.Graphics.DrawLine(Pens.White, selectedRect.Right - thirdOfWidth, selectedRect.Top, selectedRect.Right - thirdOfWidth, selectedRect.Bottom);
        e.Graphics.DrawRectangle(pen, selectedRect);
        e.Graphics.DrawLine(pen, selectedRect.Left, selectedRect.Top + thirdOfHeight, selectedRect.Right, selectedRect.Top + thirdOfHeight);
        e.Graphics.DrawLine(pen, selectedRect.Left, selectedRect.Bottom - thirdOfHeight, selectedRect.Right, selectedRect.Bottom - thirdOfHeight);
        e.Graphics.DrawLine(pen, selectedRect.Left + thirdOfWidth, selectedRect.Top, selectedRect.Left + thirdOfWidth, selectedRect.Bottom);
        e.Graphics.DrawLine(pen, selectedRect.Right - thirdOfWidth, selectedRect.Top, selectedRect.Right - thirdOfWidth, selectedRect.Bottom);
      }
    }
  }

The result is this (I got rid of my main form drawing routine and inserted a nice background picture instead). Very nice!

Rubberband-demo-3

Update: As requested, I’m making the complete sample project available. Here’s the download.

Enter your email address:

Search

Oliver
MVP logo
October 2006
Sun Mon Tue Wed Thu Fri Sat
 << < Current> >>
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31