In .NET window forms a form have collection of control and internally all of them is just wrap around window subsystem provided by Microsoft windows. Somewhat similar to MFC which is a shallow wrapper around window api. The controls in a form/window create a tree structure and events are received by the leaf nodes e.g. MouseMove event will be receive by window/control directly underneath the mouse.
But in presentation framework microsoft provided RoutedEvent which can have one of following strategies
My guess is that presentation framework create just one main window and does the drawing by itself for child elements to support the event routing strategies
Now can I change this strategy in my normal window form. I want Tunnel or Bubble and currently window system uses Direct. I want it to receive MouseEnter/MouseLeave event even if there are controls on top of it. One way is Global mouse/keyboard hook. But let say i want to avoid that.
Windows has bubbling but it is purely based on the message. MouseWheel bubbles for example, but neither MouseEnter nor Leave do. Adding bubbling behavior is technically possible but very hard to get right. Every window in the parent/child tree needs to co-operate and bubble to their parent explicitly.
It doesn't solve the problem in this specific case anyway. Key issue is that there's no guarantee that a MouseLeave for a child control will ensure a MouseEnter for the parent. Mouse move messages are not accurate enough, they don't guarantee that every traversed pixel is reported. When you have a child window close to the edge of its parent, it is quite easy to not get the MouseEnter for the parent when you move the mouse fast enough.
This is solved with mouse capture, the Control.Capture property. That ensures a mouse move message is generated even when the mouse is no longer inside the window client rectangle. However, that works well when monitoring the mouse for a single window, not for multiple windows. As soon as you click a control, the control itself usually wants to capture the mouse, canceling the one you started. A button does so for example, it wants to see the MouseUp event so it can redraw the button to show the button-up state.
Tough cookies. The only decent approach I know for this particular problem is to use a Timer. 200 msec is usually good enough, start it when the mouse enters. In the Tick event handler, use Mouse.Position and Control.PointToClient to check if the mouse is still located inside the outer window rectangle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With