ScrollViewer catching PointerPressed + PointerMoved to scroll - windows-8

I'm currently creating a little drawing program, and I've a white Grid inside a ScrollViewer.
To detect if user is drawing, I catch the PointerPressed event to set my variable isUserDrawing to true, and I catch the PointerMove event, and if isUserDrawing I do write a line where the mouse is.
It works very well with a standard mouse. But when I use the simulator to test it with touch, the ScrollViewer is catching events and start scrolling and the Grid is not anymore triggering events.
Is there anyway to make the ScrollViewer responding only with two fingers instead of one ?

No. Your options are to either put something transparent on top of the ScrollViewer and grab input events off of that or not use a ScrollViewer at all. Either way - you will need to handle scrolling and zooming yourself.

Try:
subitem.ManipulationMode = ManipulationModes.All;

If you use a child control, you can set
Child.ManipulationMode = ManipulationModes.All;
in this case the enents will not be bubbled to the scroll viewer. set
Child.ManipulationMode = ManipulationModes.System; for standard manipulations.

Related

How to listen active dragging event of an UWP UIElement?

How to track/listen active dragging event of UI Element in UWP. I added the flat CanDrag=true to enable the drag feature. Using the DragStarting and DragLeave can identify the start and end of drag. But want to get the X,Y coordinate of the UIElement on dragging. Any recommendation to achieve that? I dont want to use RenderTransform for this.
I don't think it's possible in standard Drag'n'Drop flow.
There're few options but they look like a crutch.
You may use manipulations and subscribe to Delta event. That's where RenderTransform comes in.
You may start some time loop and get visual position each frame. (The most crutchy idea)
Try to play wih IsHitTestVisible and subscribe to PointMove of some FrameworkElement behind.
Subscribe to PointEntered and PointExited to the elements you dragging over so they could fire events.
I prefer the first one. It's simple and it's plane.

How to apply UI virtualization to ScrollViewer in WinRT

Is it possible to apply UI virtualization to ScrollViewer in WinRT. In my application I am creating a line chart with the help of Polyline(Polyline embedded inside a scrollviewver). But in the current case, If it come more than 500 points. It blocks the UI during the time of interacting with the Map. So what I am trying to achieve is to apply kind of UI virtualization to scroll view. If anyone had any idea to solve this please help me.
The way I would handle a Polyline is I would break its data into sections, perhaps screen-wide ones (assuming horizontal-only scrolling), put a Canvas inside of the ScrollViewer, make the size (Width) of the Canvas the total size of the chart and put a few (say 5) Polyline controls in it and then on the ViewChanged event update the Polyline controls' Canvas.Left and Points properties to correspond to the area around the current view port of the ScrollViewer. That should give you smooth scrolling. Just don't add/remove or update the controls on each ViewChanged and only update Canvas.Left and Points when you need to - that is when you don't have a Polyline ready to display next to the current view port.

ScrollViewer and handling manipulation events on child elements

I have created a Windows 8 Store App using C# / XAML. My interface includes a scrollable list, which is rendered using an ScrollViewer. I would like to be able to handle manipulation events on the elements within the list, however, setting ManipulationMode to anything other than None on the list element causes my list to no longer scroll.
Here is a simplified version of the UI:
<ScrollViewer>
<Border/> <!-- these contain child content -->
<Border/>
<Border/>
<!-- Set ManipulationMode on an element in order to receive manipulation events -->
<!-- This causes the scroll viewer to stop working! -->
<Border ManipulationMode="All"
ManipulationDelta="..."/>
<Border/>
<Border/>
</ScrollViewer>
I understand that the WinRT ScrollViewer uses a special ManipulationMode of System for performance reasons, but I would like to have a vertically scrolling list, containing elements that respond to horizontal manipulation / gestures. Can anyone think of a creative workaround that would make this possible?
it may be long time but didn't find any good solution. I just achieved what I wanted very easily.
public MovableGrid()
{
ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.System;
AddHandler(ManipulationDeltaEvent, new ManipulationDeltaEventHandler(UIElement_OnManipulationDelta), true);
AddHandler(ManipulationCompletedEvent, new ManipulationCompletedEventHandler(UIElement_OnManipulationCompleted), true);
}
I wanted my MovableGrid to be moved on X axis and I have list of MovableGrids which I wanted to be scrolled with scrollviewer. That's enough to do that.
What I have done was I put a transparent rectangle on top of the ScrollViewer and handle manipulations there. When I find the manipulation should scroll the ScrollViewer - I scroll the ScrollViewer using the ScrollToHorizontal/VerticalOffset() methods. On ManipulationStarted I also use VisualTreeHelper.FindElementsInHostCoordinates to check which item I could manipulate too and then I can decide whether to manipulate that item or not depending on various conditions. It's quite a bit of custom code though. You would also need to update the RenderTransform of the ScrollContentPresenter in the ScrollViewer when the user tries to drag farther than minimum/maximum offset to immitate the ScrollViewer default behavior, handle mouse scrollwheel etc. Nothing YOU could not handle of course. I could not find a better way unfortunately and I am interested if someone finds one.
EDIT* Another solution I thought of when trying to answer another similar question was to use another ScrollViewer as a child item and use its ViewChanged events instead of manipulation events.
EDIT 2*
Also with Windows 8.1 you get ManipulationModes.System which combined with other modes should allow you to handle manipulations inside of a ScrollViewer. Then you can call CancelDirectManipulations() on the manipulated element once you want its parent ScrollViewers to stop processing manipulations for pan&zoom.

SL 4: ScrollViewer - RequestBringIntoView

How can I find the component in a ScrollViewer that handles the RequestBringIntoView event?
It isn't exposed on the two ScrollBar parts (not directly, anyway).
Thanks for any pointers...
UPDATE: Related: Can I get the ScrollContentPresenter part of the ScrollViewer? How?
Thanks --
Bigger picture:
We have a large Canvas contained in a ScrollViewer. At runtime, an arbitrary number of UserControls (I'll call them 'Blobs') are added to the canvas from the db. Their position and content come from the db. A user can 'select' a blob by clicking on it, and its appearance changes to indicate it is selected.
If the user uses a scrollbar to move the selected blob out of view, then clicks on another blob, the Canvas is scrolled so the previously-out-of-view blob is in view again. I assume this is due to some object raising the RequestBringIntoView, and the ScrollViewer is handling it.
Hope this makes sense...
Yet more info:
Added a handler (sb_ValueChanged) to the Scrollviewer's scrollbar ValueChanged event. Here's the stack from the mouse click that precipitates the scrolling:
OurControl.sb_ValueChanged() System.Windows.dll!System.Windows.Controls.Primitives.RangeBase.OnValueChanged() System.Windows.dll!System.Windows.Controls.Primitives.ScrollBar.OnValueChanged() System.Windows.dll!System.Windows.Controls.Primitives.RangeBase.OnValuePropertyChanged()
System.Windows.dll!System.Windows.DependencyObject.RaisePropertyChangeNotifications()
System.Windows.dll!System.Windows.DependencyObject.UpdateEffectiveValue()
System.Windows.dll!System.Windows.DependencyObject.SetValueInternal()
System.Windows.dll!System.Windows.DependencyObject.SetValue()
System.Windows.dll!System.Windows.Controls.ScrollViewer.InvalidateScrollInfo() System.Windows.dll!System.Windows.Controls.ScrollContentPresenter.VerifyScrollData()
System.Windows.dll!System.Windows.Controls.ScrollContentPresenter.ArrangeOverride()
System.Windows.dll!System.Windows.FrameworkElement.ArrangeOverride()
If only I could find out what the FrameworkElement that starts the mischief actually is...
Sorry... it doesn't seems to exist like it does in WPF. Check this link for a handy solution.
Update: Ok... for this you might need to walk the visual tree and some sort of recursive search need to be done. However, assuming you are using the default template for the scrollviewer as seen here, you can directly ask for the ScrollContentPresenter with something like this:
var BorderChild = VisualTreeHelper.GetChild(MyScrollViewer, 0);
var GridChild = VisualTreeHelper.GetChild(BorderChild, 0);
var ScrollContentPresenterChild = VisualTreeHelper.GetChild(GridChild, 0);

How can I show scrollbars on a PictureBox control?

Sometimes, I have a picturebox lets say 100x100. But the image it will display is actually 100x400.
I don't want to increase the size of the picturebox itself. Instead, I would like to create a vertical scrollbar (or horizontal if needed).
I could not find a scrollbar in the toolbox, so I guess I have to code it. But, how?
And I still wonder if I didn't make a mistake and didn't see the scrollbar in the toolbox. My apologies then :(
I suppose you could add separate scrollbar controls and sync their Scroll events up with the offset at which the picture in the PictureBox is drawn, but that sounds like actual work. There's a better way.
Add a Panel control to your form, and set its AutoScroll property to "True". This will cause the control to automatically show scrollbars when it contains content that lies outside of its currently visible bounds. The .NET Framework will take care of everything for you under the covers, without you having to write a single line of code.
Drag and drop your PictureBox control inside of the Panel control that you just added. The Panel control will then detect that one of its child controls is larger than its visible area and show scrollbars, thanks to the AutoScroll property. When the user moves the scrollbars, the portion of the image in your PictureBox that is visible will be automatically adjusted. Magic.
(The reason you have to use a Panel control as a container is because PictureBox does not inherit directly from the ScrollableControl base class, which is what provides the AutoScroll property.)
I tried this and it worked well. But I noted that if the picturebox is docked in the panel, the picturebox is automatically set to the size of the parent panel, and can't be set larger (at least not in any way I could find). This defeats the purpose of the technique. So -- put the picturebox on the panel, but don't dock it, and it will work perfectly.
There are no automatic scroll bars on a picture box, but you can add the VScrollBar (and HScrollBar) control to the form and handle the image scrolling manually by redrawing it at a different offset each time the Scroll event is fired.