Specifically, I have a custom user control that receives manipulation events to scroll a custom DirectX control. This control, and others like it, are items in a GridView. I want the GridView to be able to scroll horizontally through the default TranslateRailsX manipulation, while the controls should be able to receive TranslateRailsY manipulation events.
In my experiments so far, by setting the controls' manipulation mode to System, I can get the GridView scroll to work, but the controls will not receive any manipulation events. By setting the controls' manipulation mode to All, or TranslateY, or TranslateRailsY, I can get my custom control to receive the manipulation events, but the GridView touch scroll will not work.
How can I allow BOTH of these manipulations?
It can't be done with 8.0 (for 8.1 scroll to EDIT). You would need to implement your own ScrollViewer to use in the GridView template or put a layer on top of the GridView and relay all input calls as I suggested before. Actually, perhaps implementing your own version of ScrollViewer wouldn't be that hard (a Canvas control with one child that calls Canvas.SetLeft on its child item on manipulation events).
One new idea I have that might work for you is to put another ScrollViewer in front of your DirectX control and use its ViewChanged events as you would use the manipulation events - check this:
XAML
<Page
x:Class="App84.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App84"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid
Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<GridView>
<Grid
Width="300"
Height="300">
<Rectangle
x:Name="DirectXControlPlaceholder"
Width="300"
Height="300"
Fill="Yellow" />
<ScrollViewer
x:Name="ManipulationCaptureScrollViewer"
Style="{StaticResource VerticalScrollViewerStyle}"
VerticalScrollBarVisibility="Hidden"
ViewChanged="ScrollViewer_OnViewChanged">
<Rectangle
Width="200"
Height="10000"
Fill="Transparent"/>
</ScrollViewer>
<TextBlock
x:Name="OffsetTextBlock"
Foreground="Black"
FontSize="24"
VerticalAlignment="Center"
HorizontalAlignment="Center"
/>
</Grid>
<Rectangle
Width="300"
Height="300"
Fill="GreenYellow" />
<Rectangle
Width="300"
Height="300"
Fill="LimeGreen" />
<Rectangle
Width="300"
Height="300"
Fill="Red" />
<Rectangle
Width="300"
Height="300"
Fill="OrangeRed" />
<Rectangle
Width="300"
Height="300"
Fill="DarkOrange" />
<Rectangle
Width="300"
Height="300"
Fill="Orange" />
</GridView>
</Grid>
</Page>
Code behind
using Windows.UI.Xaml.Controls;
namespace App84
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void ScrollViewer_OnViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
OffsetTextBlock.Text =
ManipulationCaptureScrollViewer.VerticalOffset.ToString();
}
}
}
EDIT*
Also with Windows 8.1 you get ManipulationModes.System
which combined with other modes (scale and rotate are not supported though) 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.