In WinRT, the ScrollViewer is a convenient control that supports Zoom/Pan features for its content in default. But I got stuck on controlling the Zoom/Pan features of the ScrollViewer's content in code-behind(c-sharp file). If I know how ScrollViewer works, the problem should be solved as expected.
Note: I've tried to write the event-handling method to listen to ScrollViewer's ManipulationXXX event, but it hadn't been run into. Only I can listen to ScrollViewer's ViewChanged event.
I can get ScrollViewer object's ZoomFactor property which tells you the current zoom value. If you want to change the zoom value of the content, just use ZoomToFactor(float factor).
Related
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().
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.
I have made some custom attached properties that enable me to create a "pop out" effect on any control.
It animates the width and/or height when a boolean DependencyProperty is toggled.
Is there a good way to set all ScrollViewer's scrollbar visibility inside the control to hidden during this effect? You can see some ugly scrollbars appear during the animation.
I would rather not have to traverse the visual tree at the start of the animation, and then do it again when the animation completes.
EDIT: Although an alternate solution would be nice, at this point I'd rather bind to a readonly attached property named IsAnimating to handle setting the scroll visibility.
Is there a global way to to this?
Instead of animating the width of the control itself, try fixing its width at the start of the animation and reparenting it into a grid, and animate the grid's width instead. The original visual wouldn't change size in its own little world, and no scroll bars would appear or change.
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.
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.