MouseEnter and MouseLeave loops in WPF
Sorry for the cheesy blur effect, but my buddy hasn't gotten permission from the company he's working with to blog about his project yet. When we get permission I'll blog in more detail about all the fun stuff we've learned.
I'm helping a friend of mine occasionally with WPF-related questions as he works on a really good looking application that features clothing from a large US apparel manufacturer. There's a nice animation as you roll over transparent PNGs of two shirts. The shirt you're rolling over zooms to the forefront with a nice blur and zoom animation. Below the shirts is a styled Radio Button with "Mens" and "Womens" text.
There's MouseEnter and MouseLeave events hooked up
We found ourselves in a really strange situation where there was a tiny strip of pixels that, when moused over, caused an apparently Enter/Leave loop.
The screenshot below shows the System.Diagnostics.Debug.WriteLine() calls showing the output from the application. Notice that the mouse is just approaching the second men's shirt. At this point the application would freak out as it got stuck in a loop until I moved the mouse away.
This was really confusing and my knee-jerk reaction was that was somehow a bug in WPF, but then I remembered something an engineer smarted than I said:
"My code runs exactly as I wrote it."
If I go on the assumption that I haven't found a major bug in WPF, then the problem must be me. The code must be running as I wrote it.
It turns out that if you change the element that is underneath the mouse, like hiding it or changing its Z-order, you'll get a MouseLeave for the changed element and a MouseEnter for the new element that appears.
We'd gotten ourselves in a loop because we'd pushed the elements so close to together that they overlapped. One element would leave, the one underneath would popin, and the swapping would continue.
The solution was as simple as zooming in on the XAML view in the designer and moving the elements away from each other so they didn't overlap.
It was such a frustrating bug and we fought with this for an hour before we stepped back and reminded ourselves that it might just be the way we wrote it.