That's trickier than it seems, as the MouseLeftButtonUp event will be triggered only if the MouseLeftButtonDown has first been triggered on the control.
I see two ways to achieve this result:
Assign the same MouseLeftButtonDown and MouseLeftButtonUp event handler to all your rectangles. In the MouseLeftButtonDown, call the
CaptureMouse
method (it tells the control to continue tracking the mouse events even if the cursor isn't on top of the control anymore):private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { ((UIElement)sender).CaptureMouse(); }
In the MouseLeftButtonDown, release the mouse, then use the
VisualTreeHelper.FindElementsInHostCoordinates
to find the rectangle on which the cursor was when the even was triggered:private void MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { var element = (UIElement)sender; element.ReleaseMouseCapture(); var mouseUpRectangle = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(this), this.ContentPanel) .OfType<Rectangle>() .FirstOrDefault(); if (mouseUpRectangle != null) { Debug.WriteLine("MouseUp in " + mouseUpRectangle.Name); } }
(replace ContentPanel by the name of the container in which you've put all your controls)
Not tested but it might work. Subscribe to the MouseLeftButtonUp event of the container in which you've put all your rectangles. Then use the same logic to retrieve the rectangle at the coordinates of the pointer:
private void MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { var mouseUpRectangle = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(this), this.ContentPanel) .OfType<Rectangle>() .FirstOrDefault(); if (mouseUpRectangle != null) { Debug.WriteLine("MouseUp in " + mouseUpRectangle.Name); } }
You can find more information in that article I wrote a few months ago.