Mouse wheel not working when over ScrollViewer's child controls - c#

I was kind of expecting my ScrollViewer's child controls to hand the MouseWheel events back up the the ScrollViewer automatically, and that's not the case.
I have a ScrollViewer with a ListBox in it. If I manually resize the width of the ListBox to be less than the ScrollViewer, the MouseWheel works on all of the ScrollViewer but has no effect when the mouse is positioned above the ListBox.
What's the standard way to do this? Do I put an event trigger on the ListBox that fires the event on the parent? Do I handle and reroute the event in the code behind?

The ListBox's template has a ScrollViewer in it, so that ScrollViewer will be handling the events and stopping them from propagating up the visual tree.
What exactly are you trying to achieve by having a ListBox inside a ScrollViewer? Perhaps you need to re-template the ListBox, but it's impossible to say without further info.

Related

ListView prevents scrolling of the parent page in WPF application

I have a ListView in the middle of my page in my WPF application. The problem is when the mouse cursor or my finger is above that ListView then I can't scroll down on that page (the ListView has auto size, no vertical scrolling is needed for it). How can I fix this?
Here's what I tried so far:
setting the Focusable property
setting the ScrollViewer.VerticalScrollBarVisibility to all possible values
changing the size of the ListView from auto to a fixed size
Actually, what happens(and why what you tried didnt work), was that the inner ScrollViewer inside the ListView recieved the MouseScroll events.
It handled them and the set for the RoutedEventArgs Handled="True", meaning the Page's ScrollViewer didnt get the scrolling events.
Bubbling scroll events from a ListView to its parent
You could take the above and implement it as a Behavior on your ListView.

WinForms ScrollableControl's scrollbars capture mouse wheel?

I have a custom ZoomBox control based on ScrollableControl which controls its scrollbars through AutoscrollMinSize property.
I would like to be able to handle WM_MOUSEWHEEL events to adjust control's Zoom.
I made necessary steps to make sure that the control receives the mouse events even when it is not in focus, by filtering them on the parent form.
It seems though that the events only reach the OnMouseWheel method if the control does not have its scrollbars active. If it does, it appears that the mousewheel events are being redirected to the scrollbars which handle them (by scrolling).
I would like the scrollbars to be there but only be controlled in a "traditional way", i.e. by dragging the slider or clicking on arrows etc. and handle the wheel myself. Is it possible to achieve that?
Inherit from the ScrollableControl in question and override OnMouseWheel(). In that method don't call base.OnMouseWheel().
As far as I can tell there's no other way to stop ScrollableControl from scrolling if the scroll bars are present.
A side effect is that you will no longer get MouseWheel events. Fixing that is another question. Conceptually you want to call base.base.OnMouseWheel().

How to determine when ScrollViewer started scrolling?

I'm using a Windows Phone 8.1 project and have a ScrollViewer in my XAML.
Is there an event which will fire when the ScrollViewer start scrolling? Or anyway to trigger code when ScrollViewer start scrolling?
Try ViewChanging and ViewChanged events of ScrollViewer.
Note that these events will be called multiple times during a touch manipulation. You will need to rely on IsIntermediate (in ScrollViewerViewChangedEventArgs) or IsInertial (in ScrollViewerViewChangingEventArgs) to call your code accordingly.
Update
If you want to know when a touch happens immediately I'd give the ScrollViewer's direct child, for example, a StackPanel a transparent background and then subscribe to its PointerEntered event.

Scrolling of ListView containing Expanders which contain ListViews does not work

I have the situation that my C# WPF application contains a ListView whose elements are Expanders. Each of those expanders contains a ListView with ListViewItems. Here is a picture:
On the right you can see a Scrollbar. And that ScrollBar is my problem. It has got two issues:
The ScrollBar does not work when using the MouseWheel over the expanded list. By that I mean the area from "Controller" down to "FullInstallation". If hovering over the header ("All Tests"), the ScrollBar does scroll. I think that the ListView inside the Expander by default has a ScrollBar which "steals" the MouseWheel event. However, I don't know what to do against it.
The ScrollBar scrolls over the Expander items and not the content of the expanders. By that I mean, that it is not possible to scroll a little bit down, instead you always scroll at least 1 Expander item down. I would like the scrollbar to scroll such that it is possible to see for instance one half of the "All Tests" Expander.
The picture shows a disabled scrollbar, but by making the window smaller, the scrollbar gets enabled.
What I have tried so far:
ScrollViewer outside the outer ListView: This solves Problem 1, however it means that the MouseWheel does not work at all! That is because the outer ListView generates its own ScrollViewer (used Snoop to find this out) which "steals" the MouseWheel events.
Redirected all the MouseWheel events of all the controls (ListView, Expander, ListViewItem) to the ScrollViewer: Again I used a ScrollViewer outside of the outer ListView and this time I used the MouseWheel event for all my controls to call the MouseWheel event of the outer ScrollViewer. This did work, however for some locations of the mouse pointer it didn't. For instance between two ListViewItems there is a small 1 millimeter space where the MouseWheel event is not catched. Or at the bottom after the last Expander ("Short Tests"). There I do not get any event.
I tried a couple more things but did not get any further.
Does anyone have an idea how to solve this?
Best wishes,
Christian
1) For how to write an attached behavior to control mousewheel behavior when you have nested itemscontrols, see: WPF Nested ScrollViewer / ListBox Scrolling
2) Non virtualized itemscontrol supports smooth scrolling, see: Is it possible to implement smooth scroll in a WPF listview?

In a WPF ListView how can I prevent auto scrolling?

I have a WPF ListView which currently scrolls everytime I click on an item which is only partially visible. How can I keep the control from scrolling that item into view (instead simply selecting the partially visible one)? This behavior is very annoying when doing a drag from this control.
Thanks.
Added: I am looking for a solution to keep the control itself from scrolling when contents are clicked that the control believes are not fully visible. Often this is by a few pixels and the scroll is not necessary.
The items scroll into view because the default behavior on list item click is to call BringIntoView(). You can add an event handler for the RequestBringIntoView event and catch it before it bubbles up from the ListViewItems to the ScrollViewer. In your handler, check the bounds of the sender against the visible region and if you decide that you don't need to scroll, set the event's Handled flag to true.
Since I'm currently on the road, I cannot try this, but have you tried playing around with CanContentScroll, and/or wrapping the scrollable content into a Panel, as suggested by the ScrollViewer Overview on MSDN?
In the worst case, you might want to replace the ListView's ItemsPanel by a hacked ScrollViewer with a "fuzz" factor, e.g. by capturing the RequestBringIntoView event.
have you tried this approach?
just as an addon, I don't know how much you know about the subject, but here is a good place to read more about it.
added:
I just found that you can prevent the mouse wheel of scrolling as well.

Categories