WPF ItemControl、ListBox等触摸列表同步滚动条(触摸滚动)

转发:原文作者Angus_LJH(CSDN)

原文地址:https://blog.csdn.net/qq_35351282/article/details/115490143

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
 
namespace commom
{    
    /// <summary>
    /// ScrollViewer触摸滚动
    /// 使用用例:
    /// 1、xmlns添加引用
    /// 2、ScrollViewer添加附加属性设置RollAttachHelper.IsEnabled="True" 
    /// </summary>
    public class RollAttachHelper : 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(RollAttachHelper), 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;
                target.ManipulationBoundaryFeedback += target_ManipulationBoundaryFeedback;
            }
            else
            {
                target_Unloaded(target, new RoutedEventArgs());
            }
        }
 
       static void target_Unloaded(object sender, RoutedEventArgs e)
        {
            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;
            target.ManipulationBoundaryFeedback -= target_ManipulationBoundaryFeedback;
        }
        /// <summary>
        /// 触摸屏滚动实现,禁止窗口弹跳
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void target_ManipulationBoundaryFeedback(object sender, ManipulationBoundaryFeedbackEventArgs e)
        {
            e.Handled = true;
        }
 
        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;
            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; }
        }
    }
}

 

posted @ 2022-09-22 15:33  Kacy  阅读(654)  评论(0编辑  收藏  举报