Too much "async" with this WPF
What’s this post about? This post begins with DIY. Try to do the following:
- Add simple ListView to your application
- Inside the ListView add two TextBlocks
- For each TextBlock subscribe to OnMouseDown (or any other mouse event)
- OnMouseEvent create new Window and open it with Show() method.
Did it? Fine. Have you paid your attention, that each new window opens this way goes backward? Don’t it looks a bit strange?Let’s give ListView other try.
- Add simple ListView to your application
- Inside the ListView add two TextBlocks
- Subscribe to SelectionChanged event of the listview
- OnSelectionChanged create new Window and open it with Show() method.
The same result? Maybe all collections have this bug behavior? Let’s give a try to LiveBox… Do the same as in previous try, but instead of ListView use ListBox. The behavior disappears. Now the new window opens normally over the main window. What’s the difference?
Return to second try (with SelectionChanged event), but put SelectionMode property of ListView to “simple” or “multiple”. Works fine, right. So the problem with SelectorItem selection. Let’s dive a bit deeper.
What’s actually happens? If you have rather slow computer, you can clearly see the process. First occurs ”mouse event”, then opens window at the front of openner, next the item becomes selected and steals focus. Why ListViewItem doing it? According my short investigation, the root of the problem is Automation boundary. If you have time and wish to do it, trace all events (by using global events handling) and see it yourself. If you have either time nor wish, the answer is following.
WPF process almost any operation asynchronously, so with new window opening, the item becomes selected and grab focus. How to solve this. Simple. Do your work very asynchronous way. Following the code, that opens window with normal thread priority, so it waits for openner to finish all tasks to process new job.
delegate void OpenWindowDelegate(bool bringFocus);
void OpenWindow(bool bringFocus)
{
if (!bringFocus)
{
Window1 w = new Window1();
w.Show();
}
else
{
this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
new OpenWindowDelegate(OpenWindow), false);
}
}
We finished, now your windows will be opened above the opener and you’re be able to do anything with both of those windows (ShowDialog() method or setting owner property for opened window will works fines, even without it, ‘cos it locks the focus on newly opened window.
Happy Passover to all of you. Oh, I almost forgot my original question: Does this behavior is bug or not? I’m really interested with your opinion.
April 1st, 2007 · Comments (1)
One Response to “Too much "async" with this WPF”
Leave a Reply
Discover other tags
My tools
- .NET Framework Detector
- Duplicate images finder
- Exchange Security Policy for Windows Mobile Devices Fix
- Gas Price Windows Vista SideBar gadget
- Israel Traffic Information Windows Vista SideBar gadget
- Localization fix for SAP ES Explorer for Visual Studio
- LocTester
- RTL and LTR in Windows Live Writer
- Silverlight controls library
- Snipping tool integration plugin for WLW
- USB FM receiver library
- Vista Battery Saver
- WebCam control for WPF
- Windows Live SkyDrive attachment for Windows Live Writer
- Wireless Migrator
- WPF Virtual Keyboard




January 1st, 2009 at 12:08 am
I have similar problems, with two separate windows where one basically only has a listview – called SearchResultWindow, the other has lots of stuff, amongst others a tab with a listview – this one’s the main window.
Now, if I select a row in SearchResultWindow, first time I can change focus back to main window, but if I select another row, the focus sticks to SearchResultWindow and I can’t click on anything in mainwindow (mouseover-effects work though). As long as I select a new row this behaviour stays, but if I select the row that is already selected again, the behaviour is gone and I can click on objects in mainwindow. Again if I select anoyher row, the focus is stolen to SearchResultWindow. Now, if I open the listview-tab in my mainwindow and select any row there, the strange behaviour is completely gone and cannot be reproduced until the application is restarted. I have both selectionchanged- and mouseenter/mouseleave triggers in my listview.