I have a scrollviewer with an itemscontrol, and inside of the itemscontrol are buttons. Here is the xaml:
`
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<ItemsControl Style="{DynamicResource FileItemsControlStyle}" ItemsSource="{Binding Files.Files}"
Padding="4" ManipulationBoundaryFeedback="FileListBox_ManipulationBoundaryFeedback">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Style="{StaticResource ImportsFileBorder}" Margin="0, 2" Height="75" HorizontalAlignment="Stretch">
<b:Interaction.Triggers>
<b:EventTrigger EventName="PreviewMouseDown">
<b:InvokeCommandAction Command="{Binding Path=DataContext.RenderSelectedFileCommand,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding}"/>
</b:EventTrigger>
</b:Interaction.Triggers>
<DockPanel LastChildFill="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ToggleButton IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
PreviewMouseDown="ToggleSliderButton_PreviewMouseDown" Style="{DynamicResource ToggleSliderStyle}"
DockPanel.Dock="Left" Margin="10,15,10,0" />
<TextBlock Text="{Binding DisplayFileName}" Width="Auto" VerticalAlignment="Center" FontWeight="Bold" TextTrimming="CharacterEllipsis"
FontSize="{DynamicResource LargeFontSize}" Foreground="Lime"/>
</DockPanel>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
`
My issue is that if I have PanningMode = "Both" for the scrollviewer I can scroll via my mouse and touch device perfectly fine. And if I click a button with my mouse, the style triggers and it highlights. However with touch, the buttons are not highlighting (but the buttons commands do fire). If I turn PanningMode too "None" then the styles trigger on the buttons fine (but I can't scroll obviously). I need to be able to scroll through the list of buttons even if my touch event starts on a button but somehow determine if I'm actually just clicking the button or if I'm scrolling. Ideally if I'm scrolling, the button I started on to begin the scrolling wouldn't highlight.
I found another Stackoverflow article here: WPF, ScrollViewer consuming touch before longpress
and tried implementing the answer from there:
`
public class ScrollViewerWithTouch : ScrollViewer
{
/// <summary>
/// Original panning mode.
/// </summary>
private PanningMode panningMode;
/// <summary>
/// Set panning mode only once.
/// </summary>
private bool panningModeSet;
/// <summary>
/// Initializes static members of the <see cref="ScrollViewerWithTouch"/> class.
/// </summary>
static ScrollViewerWithTouch()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollViewerWithTouch), new FrameworkPropertyMetadata(typeof(ScrollViewerWithTouch)));
}
protected override void OnManipulationCompleted(ManipulationCompletedEventArgs e)
{
base.OnManipulationCompleted(e);
// set it back
this.PanningMode = this.panningMode;
}
protected override void OnManipulationStarted(ManipulationStartedEventArgs e)
{
// figure out what has the user touched
var result = VisualTreeHelper.HitTest(this, e.ManipulationOrigin);
if (result != null && result.VisualHit != null)
{
var hasButtonParent = this.HasButtonParent(result.VisualHit);
// if user touched a button then turn off panning mode, let style bubble down, in other case let it scroll
this.PanningMode = hasButtonParent ? PanningMode.None : this.panningMode;
}
base.OnManipulationStarted(e);
}
protected override void OnTouchDown(TouchEventArgs e)
{
// store panning mode or set it back to it's original state. OnManipulationCompleted does not do it every time, so we need to set it once more.
if (this.panningModeSet == false)
{
this.panningMode = this.PanningMode;
this.panningModeSet = true;
}
else
{
this.PanningMode = this.panningMode;
}
base.OnTouchDown(e);
}
private bool HasButtonParent(DependencyObject obj)
{
var parent = VisualTreeHelper.GetParent(obj);
if ((parent != null) && (parent is ButtonBase) == false)
{
return HasButtonParent(parent);
}
return parent != null;
}
}
`
However, this doesn't allow me to start scrolling if my touch starts on the buttons. Is there some way I could modify this too allow me to scroll when needed but then turn panning mode off if I'm just touching/clicking a button and allow the style too trigger?