If the other object is one of your objects, then your label and the other object can cooperate while you have the mouse captured using synthetic events. For example, in your mouse move handler, you can check Mouse.DirectlyOver
to see if it is the other object and if so, do a little bookkeeping and then call RaiseEvent
with either MouseEnter
or MouseLeave
on the other object. If you have a bunch of these objects then you just have more bookkeeping to do.
Edit:
The above refers to Mouse.DirectlyOver
which specifically does not work when the mouse is captured. To make the above more concrete and to fix that error, here is a complete working example.
Here is the markup showing a canvas, a rectangle with mouse capture handling, and an ellipse with enter/leave handling:
<Grid>
<Canvas>
<Rectangle Canvas.Left="0" Canvas.Top="0"
Fill="Red" Width="100" Height="100"
MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"
MouseMove="Rectangle_MouseMove"
MouseLeftButtonUp="Rectangle_MouseLeftButtonUp"/>
<Ellipse Canvas.Left="0" Canvas.Top="100"
Fill="Green" Width="100" Height="100"
MouseEnter="Ellipse_MouseEnter"
MouseLeave="Ellipse_MouseLeave">
<Ellipse.RenderTransform>
<ScaleTransform/>
</Ellipse.RenderTransform>
</Ellipse>
</Canvas>
</Grid>
and here are the event handlers that demonstrate how to generate synthetic enter/leave events (but only for the ellipse) while the mouse is captured:
private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var capturer = sender as FrameworkElement;
capturer.CaptureMouse();
}
bool over = false;
UIElement element;
private void Rectangle_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton != MouseButtonState.Pressed) return;
var capturer = sender as FrameworkElement;
var hit = VisualTreeHelper.HitTest(this, e.GetPosition(this));
if (hit == null) return;
var thisElement = hit.VisualHit as Ellipse;
var nowOver = thisElement != null;
if (nowOver) element = thisElement;
var args = new MouseEventArgs(Mouse.PrimaryDevice, 0);
if (!over && nowOver) { args.RoutedEvent = UIElement.MouseEnterEvent; element.RaiseEvent(args); }
if (over && !nowOver) { args.RoutedEvent = UIElement.MouseLeaveEvent; element.RaiseEvent(args); }
over = nowOver;
}
private void Rectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var capturer = sender as FrameworkElement;
capturer.ReleaseMouseCapture();
}
private void Ellipse_MouseEnter(object sender, MouseEventArgs e)
{
Debug.WriteLine("MouseEnter");
}
private void Ellipse_MouseLeave(object sender, MouseEventArgs e)
{
Debug.WriteLine("MouseLeave");
}
If you run the demo under the debugger you'lll see that the enter/leave handlers are called whether the mouse is captured or not.