5

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?

Filip Skakun
  • 31,624
  • 6
  • 74
  • 100
ColinE
  • 68,894
  • 15
  • 164
  • 232

2 Answers2

10

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.

MistyK
  • 6,055
  • 2
  • 42
  • 76
8

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.

Community
  • 1
  • 1
Filip Skakun
  • 31,624
  • 6
  • 74
  • 100
  • Wow - that is a lot of work. So you basically take care of scrolling the `ScrollViewer` yourself? Does this mean that you also have to perform you own inertia calculations so that it scrolls naturally? Or does it do this automatically when you change vertical offset? – ColinE Sep 29 '12 at 07:18
  • 1
    Manipulations in Jupiter have built-in inertia enabled by default, so you get that covered. You just need to make sure you don't squish the ScrollContentPresenter at end of list if the scrolling happens due to inertia. The manipulations are usually pretty smooth, but you could probably use ScrollViewer animations like the ones from the [WinRT XAML Toolkit](http://bit.ly/WinRTXamlToolkit) to smooth out the scrolling when using the scroll wheel. BTW, I forgot to mention you might also want to handle setting focus on items when you tap on the overlay... :) – Filip Skakun Sep 29 '12 at 21:40
  • 1
    @ColinE check my answer to [this question](http://stackoverflow.com/questions/14153038/how-to-allow-manipulations-within-listview-gridview-item-controls-while-allowing/14161596#14161596) for another solution. – Filip Skakun Jan 04 '13 at 17:12
  • Just working on yet another implementation of custom input handling on a ScrollViewer now... – Filip Skakun Nov 21 '13 at 19:57
  • 1
    It looks that ther might be another option (use AddHandler). http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.uielement.addhandler I have suceeded using this method on a grid with a transparent layer which sets it's events to handeld, however for some reasons I can't get it working with scrollviewer – Vitalij Aug 04 '14 at 22:54