I am aiming to build a ScrollViewer type of control which holds an array of buttons. The application using this scrollviewer control will be installed on touchscreen terminals. The terminals will more than likely be running windows XP.
I want the user to be able to use their finger to scroll through the buttons horizontally when there are more buttons than will fit the viewable area. Note that I dont want to display any scrollbars.
Ive learned that the 'PanningMode' property cannot be used with windows xp but only windows 7 where the touchscreen terminal supports 'Windows Touch'.
Using WPF I have built a screen which includes a scrollViewer control which in turn has a collection of buttons. I did manage to create a panning effect by overriding the windows previewMouseDown, previewMouseMove events but this creates a problem whereby the Operating System does not know if the user has pressed the scrollviewer to select a buton or touched the scrollviewer with the intention of scrolling. Basically the override method will always win and left button pressed will be true.
So i need a way to be able to scroll but still maintain the ability to click(touch) a button within the scrollviewer.
I will attach my sample code below.
If there is a possible way to do this I would be delghted to hear it :) OR!! even if there is such a control out there available to purchase I would also be interested in that.
many thanks!
XAML:
<Grid x:Name="LayoutSelector" Grid.Column="0" Grid.Row="1" DataContext="{Binding Main, Source={StaticResource MainVM}}" Height="100" >
<ScrollViewer x:Name="ScrollViewer" Width="Auto" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" PanningMode="HorizontalOnly" >
<!--<ItemsControl ItemsSource="{Binding SelectedLayout}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Left" Height="100" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>-->
<StackPanel CanHorizontallyScroll="True" Orientation="Horizontal">
<Button x:Name="Test1" Content="Button1" Width="150"/>
<Button x:Name="Test2" Content="Button1" Width="150"/>
<Button x:Name="Test3" Content="Button1" Width="150"/>
<Button x:Name="Test4" Content="Button1" Width="150"/>
<Button x:Name="Test5" Content="Button1" Width="150"/>
<Button x:Name="Test6" Content="Button1" Width="150"/>
<Button x:Name="Test7" Content="Button1" Width="150"/>
<Button x:Name="Test8" Content="Button1" Width="150"/>
<Button x:Name="Test9" Content="Button1" Width="150"/>
<Button x:Name="Test10" Content="Button1" Width="150"/>
<Button x:Name="Test11" Content="Button1" Width="150"/>
<Button x:Name="Test12" Content="Button1" Width="150"/>
</StackPanel>
</ScrollViewer>
</Grid>
c#:
using System;
using System.Globalization;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media.Effects;
using ViewModels;
namespace Views
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private Point scrollStartPoint;
private Point scrollStartOffset;
public MainWindow()
{
InitializeComponent();
Closing += (s, e) => ViewModelCreator.Cleanup();
}
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
if (ScrollViewer.IsMouseOver)
{
// Save starting point, used later when determining
//how much to scroll.
scrollStartPoint = e.GetPosition(this);
scrollStartOffset.X = ScrollViewer.HorizontalOffset;
scrollStartOffset.Y = ScrollViewer.VerticalOffset;
// Update the cursor if can scroll or not.
this.Cursor = (ScrollViewer.ExtentWidth >
ScrollViewer.ViewportWidth) ||
(ScrollViewer.ExtentHeight >
ScrollViewer.ViewportHeight) ?
Cursors.ScrollAll : Cursors.Arrow;
this.CaptureMouse();
}
base.OnPreviewMouseDown(e);
}
protected override void OnPreviewMouseMove(MouseEventArgs e)
{
//if (this.IsMouseCaptured)
//{
// Get the new scroll position.
Point point = e.GetPosition(this);
// Determine the new amount to scroll.
Point delta = new Point(
(point.X > this.scrollStartPoint.X) ?
-(point.X - this.scrollStartPoint.X) :
(this.scrollStartPoint.X - point.X),
(point.Y > this.scrollStartPoint.Y) ?
-(point.Y - this.scrollStartPoint.Y) :
(this.scrollStartPoint.Y - point.Y));
// Scroll to the new position.
ScrollViewer.ScrollToHorizontalOffset(
this.scrollStartOffset.X + delta.X);
ScrollViewer.ScrollToVerticalOffset(
this.scrollStartOffset.Y + delta.Y);
//}
base.OnPreviewMouseMove(e);
}
protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
{
if (this.IsMouseCaptured)
{
this.Cursor = System.Windows.Input.Cursors.Arrow;
this.ReleaseMouseCapture();
}
base.OnPreviewMouseUp(e);
}
}
}