In a WPF ListView how can I prevent auto scrolling? - c#

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.

Related

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().

Custom Scrolling with ListView

I've been tasked at work with creating a UserControl containing a ListView and ComboBox's for sorting the ListView data. Sorting with the Combobox's s the easy part; the part with which I'm having difficulty is implementing a method of scrolling. In the end, the control should have an Excel-like feel to it. However, sometimes the ListView is too tall or wide for where it is placed. Therefore, there two be two scrollbars somewhere on the control. One vertically moves of the ListView only, and the other moves both the ListView and ComboBox filters horizontally.
Please note in the image above that the ComboBox's do adjust themselves according to column width, but the code for that is not enabled at the moment.
What I've tried: In the control, the filter boxes are in their own panel, and the ListView has had its own panel at times. I've tried using various combinations of the HScroll/VScroll and HorizontalScroll/VerticalScroll properties and the native function ShowScrollBar() for all the controls, but nothing has worked. The only way I've gotten scrollbars to appear is by settings AutoScroll (Scrollable for the ListView) to true. Of course, the scroll bars come in pairs and work only on the same control. I also attempted to programmatically move the scroll bars, but I haven't been able to accomplish that, either.
I've got to be doing something wrong, but I'm not sure what it is. Any help is appreciated!
I think I'd go for a different solution.
If you put the ComboBoxes in a AutoSrcoll panel with the same Anchors as the ListView you would give your users the freedom to scroll the two independently.
Yes, a ScrollBar would appear and take space but I would still happily sell that as a feature, not a bug ;-)
As for handling the Scroll event of a ListView: It is hidden and you'll have to subclass it to get access to it. See here

Multiple listboxes scroll at same time?

I have 3 listboxes and I want to scroll one meanwhile others also are scrolling. I can scroll by mousewheel and drag scrollbar.
Here you go:
Two listbox scrollbar in synchronisation
Have a look at this article. It shows how this can be done by using binding and RenderTransform.
Another thing you might want to check is the ScrollViewer.ScrollChanged event. You can possibly listen to this event and set the scrolling for your listboxes as necessary.

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?

Mouse wheel not working when over ScrollViewer's child controls

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.

Categories