Scott Hanselman

MouseEnter and MouseLeave loops in WPF

January 12, 2009 Comment on this post [20] Posted in Windows Client | WPF
Sponsored By

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.

image 

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.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
January 12, 2009 13:38
Seems like you might want to add debug-mode code which walks through your images and checks for overlaps, otherwise this is a horrible little trap waiting for every minor change in layout or graphics...

January 12, 2009 17:22
Reading your post sounds so familiar. My team is in charge of the Application Framework which the Application developers use to develop the company's product. Whenever something goes wrong the first reaction from the application developers is to blame the FW even if it isn't the FW. Whenever my WPF stuff doesn't work I accept I made some mistake, but it seems when you have access to WPF team, the first reaction is to verify that WPF works much like the application developers needs verification that the application framework works.
January 12, 2009 17:32
It reminded me of something you'll see on some websites (and I might have been guilty of the bug one or twice myself), where the text you mouse over expands with a bounding box smaller then the bounding box that determines if you've left the text and it should shrink again.
What happens is that the text will flicker large and small if you're over a small 'gray' area.
January 12, 2009 17:57
@Will
...familiar to many that have tried relatively complex programming/interactivity in Flash.

Flash and Silverlight (and most web programming, really) blurs the line between programming and desktop publishing, so you get the fun problems of both, plus the new problems when the two overlap (pun intended).
tb
January 12, 2009 18:40
To be fair though, your code will run exactly as you wrote it only about 99.99999% of the time.

The rest of the time, it's .NET's fault.
January 12, 2009 21:01
ok this has nothing to do with this topic but I can't get it out of my head unless I share it with someone if not the world.

Every time I see this topic in my feed list I keep wanted to AND DO read it as "Two Mouse enters One mouse leaves".

Anyone else?
January 14, 2009 14:55
I met a proplem which is similar to this.
I put a clip into a Grid. And drag another clip, when i draged over the edge of the previous clip, i received DragLeave event, although it's still hover on the Grid and i didn't release the MouseLeftButton. I see the event routing, but it's really bothersome. :( When multi-clips, many DragEnter and DragLeave... i have to judge if it hoverd on Grid and drop the meaningless event.

any good idea? u know, i have to release resources when DragLeave.
January 14, 2009 21:10
Your friend should change the transparent of PNGs to '#00000000' (or any other except Transparent or "#00FFFFFF" ).
It should help.

If we set Transparent (or "#00FFFFFF". Transparent is "#00FFFFFF" ) we can't catch any events of mouse over this background. It is like as set HitTestVisible false.
January 14, 2009 21:21
Besides commands don't work for control with Transparent Background too.

Regards, RredCat.
January 14, 2009 22:37
That was what I suspected, XAML, WPF and SilverLight are quite shitty tools.
January 15, 2009 10:09
Seen similar behaviors with html page where css (on mouseover) would resize element causing a change in layout that would place element off mouse position. This would trigger resize and element would be back under mouse. Result was a similar dynamic loop effect you experienced.
January 15, 2009 10:44
2Flash Guy
User plays chess with PC. PC wins three times in a row.
- Fucking Windows. It is unstable again.
Right?
January 15, 2009 21:06
Hi,
I'd like to add one more point to check out. Some years ago we had a similar effect with a blinking tooltip. It turned out that the customer has changed one mouse cursor to an extra large size so the poping tooltip changed the cursor which changed the hotspot 1px sideways which in turn resulted in a mouse leave event that removed the tooltip window. loop.

Martin
January 16, 2009 3:56
I ran into this problem when trying to add an Adorner within a MouseEnter handler and removing the adorner within a MouseLeave handler. The looping "bug" resulted in the Adorner being added and removed repeatedly causing a flashing appearance on the screen?

So beings the addition of an Adorner "change[s] the element that is underneath the mouse", what would be an appropriate way to add an Adorner when the mouse enters and remove it when the mouse leaves?
January 16, 2009 10:19
Kennie

U can set IsHitTestVisible = false to prevent flashing.
January 21, 2009 0:50
When I teach new people about programming, I always share these two statements first:

1) The best thing about computers is that they will ALWAYS do what you tell them to do.
2) The worst thing about computer is that they will always do what YOU tell them to do.
January 24, 2009 7:55
From my 10+ years developing experiance, programers expect a bug in the most complex/complicated portion of their code. However, in about 90% cases, it is not there.
January 27, 2009 9:32
@Joel. I've heard a similar sentiment before

1) The best thing about computers is that they will ALWAYS do what you tell them to do.
2) The worst thing about computer is that they will ONLY do what you tell them to do.
January 29, 2009 1:53
Nice Article

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.