对需要支持滚动触摸滚动的控件添加以下代码即可
local:TouchScrolling.IsEnabled="True"后端代码
public class TouchScrolling : DependencyObject { public static bool GetIsEnabled(DependencyObject obj) { return (bool) obj.GetValue(IsEnabledProperty); } public static void SetIsEnabled(DependencyObject obj, bool value) { obj.SetValue(IsEnabledProperty, value); } public bool IsEnabled { get { return (bool) GetValue(IsEnabledProperty); } set { SetValue(IsEnabledProperty, value); } } public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(TouchScrolling), new UIPropertyMetadata(false, IsEnabledChanged)); static Dictionary<object, MouseCapture> _captures = new Dictionary<object, MouseCapture>(); static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var target = d as ScrollViewer; if (target == null) return; if ((bool) e.NewValue) { target.Loaded += target_Loaded; } else { target_Unloaded(target, new RoutedEventArgs()); } } static void target_Unloaded(object sender, RoutedEventArgs e) { System.Diagnostics.Debug.WriteLine("Target Unloaded"); var target = sender as ScrollViewer; if (target == null) return; _captures.Remove(sender); target.Loaded -= target_Loaded; target.Unloaded -= target_Unloaded; target.PreviewMouseLeftButtonDown -= target_PreviewMouseLeftButtonDown; target.PreviewMouseMove -= target_PreviewMouseMove; target.PreviewMouseLeftButtonUp -= target_PreviewMouseLeftButtonUp; } static void target_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var target = sender as ScrollViewer; if (target == null) return; _captures[sender] = new MouseCapture { VerticalOffset = target.VerticalOffset, HorticalOffset = target.HorizontalOffset, Point = e.GetPosition(target), }; } static void target_Loaded(object sender, RoutedEventArgs e) { var target = sender as ScrollViewer; if (target == null) return; System.Diagnostics.Debug.WriteLine("Target Loaded"); target.Unloaded += target_Unloaded; target.PreviewMouseLeftButtonDown += target_PreviewMouseLeftButtonDown; target.PreviewMouseMove += target_PreviewMouseMove; target.PreviewMouseLeftButtonUp += target_PreviewMouseLeftButtonUp; } static void target_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { var target = sender as ScrollViewer; if (target == null) return; target.ReleaseMouseCapture(); } static void target_PreviewMouseMove(object sender, MouseEventArgs e) { if (!_captures.ContainsKey(sender)) return; if (e.LeftButton != MouseButtonState.Pressed) { _captures.Remove(sender); return; } var target = sender as ScrollViewer; if (target == null) return; var capture = _captures[sender]; var point = e.GetPosition(target); var dy = point.Y - capture.Point.Y; var dx = point.X - capture.Point.X; if (Math.Abs(dy) > 5) { target.CaptureMouse(); } if (Math.Abs(dx) > 5) { target.CaptureMouse(); } target.ScrollToVerticalOffset(capture.VerticalOffset - dy); target.ScrollToHorizontalOffset(capture.HorticalOffset - dx); } internal class MouseCapture { public Double VerticalOffset { get; set; } public Double HorticalOffset { get; set; } public Point Point { get; set; } } }页面代码
<Window x:Class="WpfApp2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp2" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <!--定义所以button样式--> <Window.Resources> <Style TargetType="{x:Type Button}"> <Setter Property="FontFamily" Value="Times New Roman"/> <Setter Property="FontSize" Value="80"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Background" Value="Red"/> <Setter Property="Margin" Value="5"/> <Setter Property="Content" Value="111111111111111111111111111111111111111111111111111"></Setter> <Setter Property="HorizontalAlignment" Value="Left"></Setter> </Style> </Window.Resources> <WrapPanel Loaded="WrapPanel_Loaded" Name="Panel1"> <ScrollViewer local:TouchScrolling.IsEnabled="True" HorizontalScrollBarVisibility="Auto"> <StackPanel> <Button Name="Button1" Click="Button1_OnClick" Content="{Binding Path=Btn1}"/> <Button Name="Button2" Click="Button1_OnClick"/> <Button Name="Button3" Click="Button1_OnClick"/> <Button Name="Button4" Click="Button1_OnClick"/> <Button Name="Button5" Click="Button1_OnClick"/> <Button Name="Button6" Click="Button1_OnClick"/> <Button Name="Button7" Click="Button1_OnClick"/> <Button Name="Button8" Click="Button1_OnClick"/> <Button Name="Button9" Click="Button1_OnClick"/> </StackPanel> </ScrollViewer> </WrapPanel> </Window>