WPF ItemsControl 控件支持鼠标滚轮滑动

此文章意在解决在WPF中ItemsControl类型的集合控件支持鼠标滚轮操作,并可控制滚动的速度。

第一步:给ItemsControl添加滚轮事件。

this.listBox.AddHandler(ListBox.MouseWheelEvent, new MouseWheelEventHandler(list_MouseWheel), true);

第二步:实现list_MouseWheel处理函数。

 private void list_MouseWheel(object sender, MouseWheelEventArgs e)
{
            ItemsControl items = (ItemsControl)sender;
            ScrollViewer scroll = FindVisualChild<ScrollViewer>(items);
            scroll.PanningMode = PanningMode.HorizontalOnly;
            if (scroll != null)
            {
                int d = e.Delta;
                if (d > 0)
                {
                    this._HistoryListBox.ScrollSkip(-2);//此方法为集合控件的扩展方法。参数为控制滑动的速度。
                   // scroll.LineRight();
                }
                if (d < 0)
                {
                    //scroll.LineLeft();
                    this._HistoryListBox.ScrollSkip(2);
                }
                scroll.ScrollToTop();
            }
}

第三步:定义集合控件的扩展属性和方法。

  1  public static class ListBoxExtention
  2     {
  3          public static double GetHorizontalOffset(DependencyObject obj)
  4         {
  5             return (double)obj.GetValue(HorizontalOffsetProperty);
  6         }
  7 
  8         public static void SetHorizontalOffset(DependencyObject obj, double value)
  9         {
 10             obj.SetValue(HorizontalOffsetProperty, value);
 11         }
 12 
 13         /// <summary>
 14         /// 动画属性,控制水平方向移动
 15         /// </summary>
 16         public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.RegisterAttached("HorizontalOffset", typeof(double), typeof(ListBoxExtention), new UIPropertyMetadata(0.0, OnHorizontalOffsetPropertyChanged));
 17 
 18         static void OnHorizontalOffsetPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
 19         {
 20             ((ScrollViewer)sender).ScrollToHorizontalOffset((double)args.NewValue);
 21         }
 22 
 23 
 24 
 25         public static double GetVerticalOffset(DependencyObject obj)
 26         {
 27             return (double)obj.GetValue(VerticalOffsetProperty);
 28         }
 29 
 30         public static void SetVerticalOffset(DependencyObject obj, double value)
 31         {
 32             obj.SetValue(VerticalOffsetProperty, value);
 33         }
 34 
 35         // 用一个依赖属性作为verticaloffset存储器.  这使动画, 样式,绑定, 等等及其他
 36         public static readonly DependencyProperty VerticalOffsetProperty =DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(ListBoxExtention), new UIPropertyMetadata(0.0, OnVerticalOffsetPropertyChanged));
 37 
 38         static void OnVerticalOffsetPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
 39         {
 40             ((ScrollViewer)sender).ScrollToVerticalOffset((double)args.NewValue);
 41 
 42         public static void ScrollToSelectedItem(this ListBox listbox, object selectedItem)
 43         {
 44             ScrollViewer scrollHost = VisualTreeHelper.GetChild(listbox, 0) as ScrollViewer;
 45             for (DependencyObject obj2 = listbox; obj2 != null; obj2 = VisualTreeHelper.GetChild(obj2, 0))
 46             {
 47                 ScrollViewer viewer = obj2 as ScrollViewer;
 48                 if (viewer != null)
 49                 {
 50                     scrollHost = viewer;
 51                     break;
 52                 }
 53             }
 54             if (scrollHost != null && scrollHost.IsLoaded)
 55             {
 56                 double fromValue = scrollHost.HorizontalOffset;
 57                 double toValue = 0.0;
 58                 if (selectedItem != null)
 59                 {
 60                     FrameworkElement visual = listbox.ItemContainerGenerator.ContainerFromItem(selectedItem) as FrameworkElement;
 61                     if (visual != null)
 62                     {
 63                         Vector vector = VisualTreeHelper.GetOffset(visual);
 64                         toValue = (visual.ActualWidth - scrollHost.ViewportWidth) / 2 + vector.X;
 65                     }
 66                 }
 67                 DoubleAnimation animation = new DoubleAnimation(fromValue, toValue, new TimeSpan(0, 0, 0, 0, 500), FillBehavior.HoldEnd);
 68                 scrollHost.BeginAnimation(ListBoxExtention.HorizontalOffsetProperty, animation);
 69             }
 70         }
 71 
 72 
 73  
 74         public static void ScrollSkip(this ListBox listbox, int count)
 75         {
 76             ScrollViewer scrollHost = VisualTreeHelper.GetChild(listbox, 0) as ScrollViewer;
 77             for (DependencyObject obj2 = listbox; obj2 != null; obj2 = VisualTreeHelper.GetChild(obj2, 0))
 78             {
 79                 ScrollViewer viewer = obj2 as ScrollViewer;
 80                 if (viewer != null)
 81                 {
 82                     scrollHost = viewer;
 83                     break;
 84                 }
 85             }
 86             if (scrollHost != null && scrollHost.IsLoaded)
 87             {
 88                 double fromHorizontalOffset = scrollHost.HorizontalOffset;
 89                 double toHorizontalOffset = 0.0;
 90                 double fromVerticalOffset = scrollHost.VerticalOffset;
 91                 double toVerticalOffset = 0.0;
 92                 toHorizontalOffset = (scrollHost.ExtentWidth / listbox.Items.Count) * count + fromHorizontalOffset;
 93                 toVerticalOffset = (scrollHost.ExtentHeight / listbox.Items.Count) * count + fromVerticalOffset;
 94 
 95                 if (ScrollViewer.GetHorizontalScrollBarVisibility(listbox) != ScrollBarVisibility.Disabled)
 96                 {
 97                     DoubleAnimation animation = new DoubleAnimation(fromHorizontalOffset, toHorizontalOffset, new TimeSpan(0, 0, 0, 0, 800), FillBehavior.HoldEnd);
 98                     scrollHost.BeginAnimation(ListBoxExtention.HorizontalOffsetProperty, animation);
 99                 }
100                 if (ScrollViewer.GetVerticalScrollBarVisibility(listbox) != ScrollBarVisibility.Disabled)
101                 {
102                     DoubleAnimation animation = new DoubleAnimation(fromVerticalOffset, toVerticalOffset, new TimeSpan(0, 0, 0, 0, 800), FillBehavior.HoldEnd);
103                     scrollHost.BeginAnimation(ListBoxExtention.VerticalOffsetProperty, animation);
104                 }
105             }
106         }
107 
108         public static void ScrollSkip_Double(this ListBox listbox, Double count)
109         {
110             ScrollViewer scrollHost = VisualTreeHelper.GetChild(listbox, 0) as ScrollViewer;
111             for (DependencyObject obj2 = listbox; obj2 != null; obj2 = VisualTreeHelper.GetChild(obj2, 0))
112             {
113                 ScrollViewer viewer = obj2 as ScrollViewer;
114                 if (viewer != null)
115                 {
116                     scrollHost = viewer;
117                     break;
118                 }
119             }
120             if (scrollHost != null && scrollHost.IsLoaded)
121             {
122                 double fromHorizontalOffset = scrollHost.HorizontalOffset;
123                 double toHorizontalOffset = 0.0;
124                 double fromVerticalOffset = scrollHost.VerticalOffset;
125                 double toVerticalOffset = 0.0;
126                 toHorizontalOffset = (scrollHost.ExtentWidth / listbox.Items.Count) * count + fromHorizontalOffset;
127                 toVerticalOffset = (scrollHost.ExtentHeight / listbox.Items.Count) * count + fromVerticalOffset;
128 
129                 if (ScrollViewer.GetHorizontalScrollBarVisibility(listbox) != ScrollBarVisibility.Disabled)
130                 {
131                     DoubleAnimation animation = new DoubleAnimation(fromHorizontalOffset, toHorizontalOffset, new TimeSpan(0, 0, 0, 0, 800), FillBehavior.HoldEnd);
132                     scrollHost.BeginAnimation(ListBoxExtention.HorizontalOffsetProperty, animation);
133                 }
134                 if (ScrollViewer.GetVerticalScrollBarVisibility(listbox) != ScrollBarVisibility.Disabled)
135                 {
136                     DoubleAnimation animation = new DoubleAnimation(fromVerticalOffset, toVerticalOffset, new TimeSpan(0, 0, 0, 0, 800), FillBehavior.HoldEnd);
137                     scrollHost.BeginAnimation(ListBoxExtention.VerticalOffsetProperty, animation);
138                 }
139             }
140         }
141     }
View Code

 

posted @ 2015-09-08 12:14  及乌及国  阅读(1780)  评论(0编辑  收藏  举报