WPF DevExpress按住鼠标下拉滑动列表功能

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using DevExpress.Xpf.Grid;

namespace Client
{
   public class AutoScrollHelper
   {
       public AutoScrollHelper(TableView view, int thresholdInner = 200, int thresholdOutter = 200, int horizontalScrollStep = 50)
       {
           if (view == null || view.Grid == null)
           {
               throw new ArgumentNullException("view or Grid cannot be null");
           }
           ThresholdInner = thresholdInner;
           ThresholdOutter = thresholdOutter;
           HorizontalScrollStep = horizontalScrollStep;
           fGrid = view.Grid;
           fView = view;
           fScrollInfo = new ScrollInfo(this, view);
       }

       private GridControl fGrid;
       private TableView fView;
       private ScrollInfo fScrollInfo;

       public int ThresholdInner = 200;
       public int ThresholdOutter = 200;
       public int HorizontalScrollStep = 50;
       public int ScrollTimerInterval
       {
           get => (int)fScrollInfo.scrollTimer.Interval.TotalMilliseconds;
           set => fScrollInfo.scrollTimer.Interval = TimeSpan.FromMilliseconds(value);
       }

       public void ScrollIfNeeded()
       {
           Point pt = Mouse.GetPosition(fView);
           Rect rect = new Rect(0, 0, fView.ActualWidth, fView.ActualHeight);

           fScrollInfo.GoLeft = (pt.X > rect.Left - ThresholdOutter) && (pt.X < rect.Left + ThresholdInner);
           fScrollInfo.GoRight = (pt.X > rect.Right - ThresholdInner) && (pt.X < rect.Right + ThresholdOutter);
           fScrollInfo.GoUp = (pt.Y < rect.Top + ThresholdInner) && (pt.Y > rect.Top - ThresholdOutter);
           fScrollInfo.GoDown = (pt.Y > rect.Bottom - ThresholdInner) && (pt.Y < rect.Bottom + ThresholdOutter);
       }

       internal class ScrollInfo
       {
           internal DispatcherTimer scrollTimer;
           private TableView view;
           private bool left, right, up, down;

           private readonly AutoScrollHelper owner;

           public ScrollInfo(AutoScrollHelper owner, TableView view)
           {
               this.owner = owner;
               this.view = view;
               this.scrollTimer = new DispatcherTimer();
               this.scrollTimer.Interval = TimeSpan.FromMilliseconds(100); // 默认间隔
               this.scrollTimer.Tick += ScrollTimer_Tick;
           }

           public bool GoLeft
           {
               get => left;
               set
               {
                   if (left != value)
                   {
                       left = value;
                       CalcInfo();
                   }
               }
           }

           public bool GoRight
           {
               get => right;
               set
               {
                   if (right != value)
                   {
                       right = value;
                       CalcInfo();
                   }
               }
           }

           public bool GoUp
           {
               get => up;
               set
               {
                   if (up != value)
                   {
                       up = value;
                       CalcInfo();
                   }
               }
           }

           public bool GoDown
           {
               get => down;
               set
               {
                   if (down != value)
                   {
                       down = value;
                       CalcInfo();
                   }
               }
           }

           private void ScrollTimer_Tick(object sender, EventArgs e)
           {
               owner.ScrollIfNeeded();

               var scrollViewer = FindVisualChild<ScrollViewer>(owner.fGrid);

               if (scrollViewer != null)
               {
                   if (GoDown)
                       view.TopRowIndex++;
                   if (GoUp)
                       view.TopRowIndex--;
                   if (GoLeft)
                       scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - owner.HorizontalScrollStep);
                   if (GoRight)
                       scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + owner.HorizontalScrollStep);
               }

               if (!Mouse.LeftButton.HasFlag(MouseButtonState.Pressed))
                   scrollTimer.Stop();
           }

           private void CalcInfo()
           {
               if (!(GoDown && GoLeft && GoRight && GoUp))
                   scrollTimer.Stop();

               if (GoDown || GoLeft || GoRight || GoUp)
                   scrollTimer.Start();
           }

           private static T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
           {
               for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
               {
                   var child = VisualTreeHelper.GetChild(parent, i);
                   if (child is T typedChild)
                   {
                       return typedChild;
                   }

                   var childOfChild = FindVisualChild<T>(child);
                   if (childOfChild != null)
                   {
                       return childOfChild;
                   }
               }
               return null;
           }
       }
   }
}
posted @   蹲着马桶抽烟  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示