Answered by:
Bug: Scrolling with mouse wheel stops working in a ListView if the page contains WebView?

Question
-
Is this a known bug with mouse wheel scrolling when a page contains webview.
Steps to reproduce:
1) Add a Split Page to project.
2) Add a WebView on right hand side and call WebView.NavigateToString() method in ListView's SelectionChanged event.
3) Scrolling stops working with mouse wheel in a list view.
Cmpi1in9 it..
Friday, July 6, 2012 9:35 AM
Answers
-
Hi Gaurav,
This is just an unfortunate side effect of the fact that under the covers, the WebView control is not a XAML Control like the others, but rather a fully separate Hwnd.
I don't see any easy solution to have mouse wheel work for either your webview OR your listview, since implementing something like this would require being able to Focus() the WebView when hovering back over it, and it's simply not a control.
Suggested workarounds:
1) Handle WebView.GotFocus event, set focus back to your listView (solves the problems of "calling Focus() on LoadCompleted" issue)
Something like:
private void mrWebView_GotFocus_1(object sender, RoutedEventArgs e) { itemListView.Focus(Windows.UI.Xaml.FocusState.Pointer); }
(but you can get more clever using FocusManager to decide what to focus)2) Handle PointerEntered event of your ListView, so that you can explicitly Focus() it when the pointer enters it, and send focus elsewhere (but, as noted, not your WebView) on exit / cancelled if desired.
3) Use WebViewBrush instead of WebView... but this has the unfortunate side effect of losing input for your WebView, so probably not the best solution.
I've filed a bug to track this issue, but at this point in the release cycle it's uncertain whether it'd get fixed. I can get about 90% of the solution you want locally, but getting focus back into WebView after programmatically removing it just doesn't seem possible (without another Navigate() call... which is hacky).
Hope this helps,
MattXAML SDET Lead : Input / DirectManipulation / Accessibility
- Marked as answer by Min ZhuMember Friday, August 10, 2012 9:47 AM
Wednesday, July 11, 2012 10:58 PM
All replies
-
Hi gaurav,
It seems to be a bug.I too faced this situation.But,when I navigate just back to settings menu on right hand side(Charm) and come back to Webview to scroll, it works well.
Subramanian Muthukrishnan Microsoft Student Partner iLink Systems General Secretary,Rockcity Dot Net User Group Windows 8 Trainer,DPE Program for Windows 8,Microsoft.
Saturday, July 7, 2012 10:30 AM -
Thanks for your confirmation. It seems others are facing this problem too... http://stackoverflow.com/questions/10311713/windows8-metro-webview-navigatetostring-disturbs-scrolling-in-grid
Cmpi1in9 it..
Monday, July 9, 2012 5:52 PM -
This is because current focus on the webview and the scrolling will scroll the webview only. You need add code to remove the focus after navigateToString().Monday, July 9, 2012 9:32 PM
-
Correct one thing, you should add the remove focus code after the content load completed.
private void webView1_LoadCompleted(object sender, NavigationEventArgs e)
{
this.itemListView.Focus(Windows.UI.Xaml.FocusState.Programmatic);
}
- Proposed as answer by Xianghan WangMicrosoft employee Monday, July 9, 2012 11:29 PM
- Unproposed as answer by gaurav77 Tuesday, July 10, 2012 8:49 AM
- Proposed as answer by Xianghan WangMicrosoft employee Tuesday, July 10, 2012 5:46 PM
Monday, July 9, 2012 11:29 PM -
It does not work in following cases:
- Suppose, the html contains link to online images, in that case LoadCompleted() event is not fired till all images are loaded which could take more than few seconds. Thus, user will not be able to scroll through list.
- I tried setting focus to listview just after navigateToString() call, but that does NOT work too.
- Another issue, once you set focus to listview in LoadCompleted() event, then mouse scrolling stops working in webview. Shouldn't webview get the focus automatically when mouse enters over it.
- Another problem, WebView doesn't even have a Focus() method.
These are fairly basic problems I encounter when writing a simple news app that should work fine with mouse. I hope they're already fixed in RTM release.
Thank you!
Cmpi1in9 it..
- Edited by gaurav77 Tuesday, July 10, 2012 9:03 AM
Tuesday, July 10, 2012 9:03 AM -
- Suppose, the html contains link to online images, in that case LoadCompleted() event is not fired till all images are loaded which could take more than few seconds. Thus, user will not be able to scroll through list.
- I tried setting focus to listview just after navigateToString() call, but that does NOT work too.
This doesn't work, as NavigateToString() call will start another thread to load the content. and if you call setting focus just after the navigatetostring call, it will be called before the content loaded, so what happens is: it start loading the content, it set focus to listview, and then content loaded, and then it focus back to the webview. That is why we should move the setting focus to the webView1_LoadCompleted().
If it takes long time to load, maybe we should set the focus in both places. (didn't verify it, you can try:))
- Proposed as answer by Xianghan WangMicrosoft employee Tuesday, July 10, 2012 5:46 PM
- Unproposed as answer by gaurav77 Wednesday, July 11, 2012 6:56 AM
Tuesday, July 10, 2012 5:46 PM -
Thanks for your quick reply.
No, it doesn't work. I've tried setting focus in both places i.e. after the NavigateToString() call and LoadCompleted() event.
There is another problem, once the ListView gains focus after LoadCompleted() event, if you mouse over to webview and try scrolling it doesn't work. And there is no programmatic way to set focus on WebView.
It's clearly a very annoying issue and bug when working with WebView controls.
Cmpi1in9 it..
Wednesday, July 11, 2012 7:02 AM -
below link might be helpful:)
Wednesday, July 11, 2012 8:08 PM -
Hi Gaurav,
This is just an unfortunate side effect of the fact that under the covers, the WebView control is not a XAML Control like the others, but rather a fully separate Hwnd.
I don't see any easy solution to have mouse wheel work for either your webview OR your listview, since implementing something like this would require being able to Focus() the WebView when hovering back over it, and it's simply not a control.
Suggested workarounds:
1) Handle WebView.GotFocus event, set focus back to your listView (solves the problems of "calling Focus() on LoadCompleted" issue)
Something like:
private void mrWebView_GotFocus_1(object sender, RoutedEventArgs e) { itemListView.Focus(Windows.UI.Xaml.FocusState.Pointer); }
(but you can get more clever using FocusManager to decide what to focus)2) Handle PointerEntered event of your ListView, so that you can explicitly Focus() it when the pointer enters it, and send focus elsewhere (but, as noted, not your WebView) on exit / cancelled if desired.
3) Use WebViewBrush instead of WebView... but this has the unfortunate side effect of losing input for your WebView, so probably not the best solution.
I've filed a bug to track this issue, but at this point in the release cycle it's uncertain whether it'd get fixed. I can get about 90% of the solution you want locally, but getting focus back into WebView after programmatically removing it just doesn't seem possible (without another Navigate() call... which is hacky).
Hope this helps,
MattXAML SDET Lead : Input / DirectManipulation / Accessibility
- Marked as answer by Min ZhuMember Friday, August 10, 2012 9:47 AM
Wednesday, July 11, 2012 10:58 PM -
Hello Matt,
Thank you very much for your response.
Yes, with the help of *Pointer* and *Focus* events, one can manage to make scrolling work effortlessly in ListView. Although in ideal situation, you wouldn't like to write such hacky code...
Anyways, I would call this a 50-50 solution, since it leads to another problem which is WebView scrolling stops working with mouse wheel when hovering back over it. And as you mentioned there is no way to solve this challenge. :-(
Thus, from users point of view, he/she simply cannot mouse hover between ListView and WebView on application screen and expect scrolling to work effortlessly.
I think this is going to be really annoying for end-user and I already fear a flood of negative ratings in store. :-(
Is there anyway you could make this a high priority issue for the team? I really hope that WebView should automatically gain focus on mouse hover in RTM release.
Regards,
Gaurav
Cmpi1in9 it..
Thursday, July 12, 2012 9:32 AM -
It's definitely a high priority issue to fix, but it's an extremely gnarly and difficult problem to solve. The Controls team takes this issue very seriously and hopes to address it soon but it's going to require fairly large changes in how the WebView control works. That said, don't get your hopes up to solve an issue like this in the current release... I recommend exploring the workarounds and deciding on one to use.
Good luck,
Matt
XAML SDET Lead : Input / DirectManipulation / Accessibility
Friday, July 13, 2012 1:11 AM -
Focus issues caused by WebView make microsoft's Ad sdk very hard to use. Ad sitting on the screen would grab focus on every reload making it pretty much unacceptable for most common scenarios.
Friday, July 13, 2012 1:47 AM -
Thanks again for prompt reply. From current release, did you mean Release Preview or Final Windows 8 release?
FYI: I also opened the bug through Microsoft Connect.
Cmpi1in9 it..
Friday, July 13, 2012 4:49 PM -
Gaurav - I meant the final Win8 release... but anything's possible, who knows.
The Mighty Duck - I think for your scenario, using either a WebView with the "Set focus back in GotFocus() event handler" could solve your problem entirely. It's the act of setting focus back to the WebView on mouse hover that doesn't have a simple solution. Something like:
1) When you want to update your ad, you ask the FocusManager for the currently focused element, and store this off somewhere.
2) Navigate your webview
3) When WebView gets focus, set focus back to the element you noted in #1.
-Matt
XAML SDET Lead : Input / DirectManipulation / Accessibility
Friday, July 13, 2012 9:13 PM -
Hi Matt,
Since Windows 8 has RTM'd, can you please let us know if there is any update on issue.
Thanks again!
Cmpi1in9 it..
Friday, August 3, 2012 7:53 AM -
Hi all
i found the same issue on RTM
Jérémy Jeanson MVP, MCP, MCTS http://blogs.codes-sources.com/JeremyJeanson/ (French or English spoken)
Wednesday, September 5, 2012 1:15 PM -
Yes, hoping it will be fixed soon. ?!?!
Delaying my app launch, since it will be annoying for end-user to notice lack of scrolling with mouse wheel.
- Edited by gaurav77 Friday, September 7, 2012 3:48 PM
Friday, September 7, 2012 3:47 PM -
I am surprised how Yahoo Mail app is working. It has a ListView and a preview (look like a WebView). Are they using WebView control really? Or is it a Windows 8 JS app with iFrame?Monday, February 18, 2013 9:00 AM
-
As this thread is the only place I found a workaround to this nasty bug, I thought I'd add my solution which is slightly more generic and slightly more robust though all solutions will be slightly tailored to a specific app.
I created a MyWebView UserControl that contains a WebView and exposes an 'Html' DependencyProperty which allows me to use data binding to trigger NavigateToString(). Before calling NavigateToString(), I set a bool to 'true' and store the control that current has focus. Then, in the LoadComplete callback for WebView, if the bool is true, I set it to false and set the focus back to what it was before NavigateToString() was called.
This allows the WebView to work as expected, including links being active and navigation working without focus jumping away when the user clicks a link. It does, however, mean that the focus only returns to where it should be when the page finishes loading, including *all* images. I may try adding a .Focus() call in a WebView.GotFocus callback to fix this problem, though it will introduce other issues (what if the user moves focus before LoadComplete is called or if another NavigateToString() is called? Race conditions).public sealed partial class MyWebView : UserControl { public static DependencyProperty HtmlProperty = DependencyProperty.Register("Html", typeof(string), typeof(MyWebView), new PropertyMetadata(string.Empty, OnHtmlChanged)); private static void OnHtmlChanged(DependencyObject dob, DependencyPropertyChangedEventArgs e) { MyWebView myWebView = (MyWebView)dob; string html = (string)e.NewValue; if (html.Equals(string.Empty) || (html == null)) { html = "<html></html>"; } myWebView.focusFromHtml = true; myWebView.focusedElement = FocusManager.GetFocusedElement() as Control; myWebView.webView.NavigateToString(html); } public string Html { get { return (string)GetValue(HtmlProperty); } set { SetValue(HtmlProperty, value); } } public bool focusFromHtml = false; public Control focusedElement = null; public MyWebView() { InitializeComponent(); } private void webView_LoadCompleted(object sender, NavigationEventArgs e) { if (focusFromHtml) { focusFromHtml = false; if (focusedElement != null) { focusedElement.Focus(Windows.UI.Xaml.FocusState.Programmatic); } } } }
TedHoward
- Proposed as answer by Ted_Howard Saturday, February 23, 2013 4:46 PM
Saturday, February 23, 2013 4:46 PM -
But how to give focus back to webview when pointer entered?Tuesday, April 23, 2013 7:24 AM