我的目标是构建一个 ScrollViewer 类型的控件,其中包含一组按钮。使用此滚动查看器控件的应用程序将安装在触摸屏终端上。终端很可能会运行 Windows XP。
当按钮数量超过可视区域时,我希望用户能够使用手指水平滚动按钮。请注意,我不想显示任何滚动条。
我了解到“PanningMode”属性不能与 windows xp 一起使用,但只能用于触摸屏终端支持“Windows Touch”的 windows 7。
使用 WPF,我构建了一个屏幕,其中包含一个 scrollViewer 控件,该控件又具有一组按钮。我确实设法通过覆盖 windows previewMouseDown、previewMouseMove 事件来创建平移效果,但这会产生一个问题,即操作系统不知道用户是否按下滚动查看器以选择按钮或触摸滚动查看器以进行滚动。基本上,覆盖方法将始终获胜,并且按下左键将是正确的。
所以我需要一种能够滚动但仍然能够在滚动查看器中单击(触摸)按钮的方法。
我将在下面附上我的示例代码。
如果有可能的方法来做到这一点,我会很高兴听到它:) 或者!!即使有这样的控件可供购买,我也会对此感兴趣。
非常感谢!
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);
}
}
}