IAbstract
IAbstract

Reputation: 19871

Capturing the mouse

I have a List<Rectangle> myRectangles that are rendered in a Panel control. If I want to fire an event handler when the mouse is within any of myRectangles, is my best option to do 'foreach'? And then go do whatever myRectangle.OnMouseMove() would do?

Upvotes: 0

Views: 366

Answers (4)

Hans Passant
Hans Passant

Reputation: 941218

Don't use controls for your rectangles, they are horribly expensive and can't overlap. You can't make it reliable with just the OnMouseMove() method, you'll miss the mouse moving outside of the panel when the user is moving the mouse fast and/or an edge of a rectangle is close to the panel border. It is easily solved with the Control.Capture property. Some sample code:

  public event EventHandler InsideRectangles;
  private List<Rectangle> mRectangles = new List<Rectangle>();
  private bool mInside;

  protected void OnInsideRectangles(EventArgs e) {
    EventHandler handler = InsideRectangles;
    if (handler != null) handler(this, e);
  }

  protected override void OnMouseMove(MouseEventArgs e) {
    bool inside = false;
    foreach (var rc in mRectangles) {
      if (rc.Contains(e.Location)) {
        inside = true;
        break;
      }
    }
    if (inside && !mInside) OnInsideRectangles(EventArgs.Empty);
    this.Capture = inside;
    mInside = inside;
    base.OnMouseMove(e);
  }

Upvotes: 1

Zach Johnson
Zach Johnson

Reputation: 24212

I assume you must be using Winforms? If so, you might want to consider making the rectangles separate child controls (rendering whatever the rectangle looks like in OnPaint) and use the mouse events provided by Control.

Upvotes: 0

James Black
James Black

Reputation: 41858

This would seem to be a good use for Reactive LINQ, or Rx, but I am more familiar with using the former.

http://tomasp.net/blog/reactive-ii-csevents.aspx

You will want to optimize to determine which rectangles may be possibly intersected, but just use the OnMouseMove and then in your LINQ query you will find whichever rectangles are entered.

This could potentially be a performance hog.

Upvotes: 2

Yuriy Faktorovich
Yuriy Faktorovich

Reputation: 68667

You could create a control which has two rectangles one inside another. The outside rectangle's OnMouseMove would be exposed. The outside rectangle would be invisible. This way you could let Windows manage the event calling and not have cluttered code.

Upvotes: 0

Related Questions