您的位置:首页 > 其它

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

2015-09-08 12:14 495 查看
此文章意在解决在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();
}
}

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

public static class ListBoxExtention
{
public static double GetHorizontalOffset(DependencyObject obj)
{
return (double)obj.GetValue(HorizontalOffsetProperty);
}

public static void SetHorizontalOffset(DependencyObject obj, double value)
{
obj.SetValue(HorizontalOffsetProperty, value);
}

/// <summary>
/// 动画属性,控制水平方向移动
/// </summary>
public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.RegisterAttached("HorizontalOffset", typeof(double), typeof(ListBoxExtention), new UIPropertyMetadata(0.0, OnHorizontalOffsetPropertyChanged));

static void OnHorizontalOffsetPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
((ScrollViewer)sender).ScrollToHorizontalOffset((double)args.NewValue);
}

public static double GetVerticalOffset(DependencyObject obj)
{
return (double)obj.GetValue(VerticalOffsetProperty);
}

public static void SetVerticalOffset(DependencyObject obj, double value)
{
obj.SetValue(VerticalOffsetProperty, value);
}

// 用一个依赖属性作为verticaloffset存储器.  这使动画, 样式,绑定, 等等及其他
public static readonly DependencyProperty VerticalOffsetProperty =DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(ListBoxExtention), new UIPropertyMetadata(0.0, OnVerticalOffsetPropertyChanged));

static void OnVerticalOffsetPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
((ScrollViewer)sender).ScrollToVerticalOffset((double)args.NewValue);

public static void ScrollToSelectedItem(this ListBox listbox, object selectedItem)
{
ScrollViewer scrollHost = VisualTreeHelper.GetChild(listbox, 0) as ScrollViewer;
for (DependencyObject obj2 = listbox; obj2 != null; obj2 = VisualTreeHelper.GetChild(obj2, 0))
{
ScrollViewer viewer = obj2 as ScrollViewer;
if (viewer != null)
{
scrollHost = viewer;
break;
}
}
if (scrollHost != null && scrollHost.IsLoaded)
{
double fromValue = scrollHost.HorizontalOffset;
double toValue = 0.0;
if (selectedItem != null)
{
FrameworkElement visual = listbox.ItemContainerGenerator.ContainerFromItem(selectedItem) as FrameworkElement;
if (visual != null)
{
Vector vector = VisualTreeHelper.GetOffset(visual);
toValue = (visual.ActualWidth - scrollHost.ViewportWidth) / 2 + vector.X;
}
}
DoubleAnimation animation = new DoubleAnimation(fromValue, toValue, new TimeSpan(0, 0, 0, 0, 500), FillBehavior.HoldEnd);
scrollHost.BeginAnimation(ListBoxExtention.HorizontalOffsetProperty, animation);
}
}

public static void ScrollSkip(this ListBox listbox, int count)
{
ScrollViewer scrollHost = VisualTreeHelper.GetChild(listbox, 0) as ScrollViewer;
for (DependencyObject obj2 = listbox; obj2 != null; obj2 = VisualTreeHelper.GetChild(obj2, 0))
{
ScrollViewer viewer = obj2 as ScrollViewer;
if (viewer != null)
{
scrollHost = viewer;
break;
}
}
if (scrollHost != null && scrollHost.IsLoaded)
{
double fromHorizontalOffset = scrollHost.HorizontalOffset;
double toHorizontalOffset = 0.0;
double fromVerticalOffset = scrollHost.VerticalOffset;
double toVerticalOffset = 0.0;
toHorizontalOffset = (scrollHost.ExtentWidth / listbox.Items.Count) * count + fromHorizontalOffset;
toVerticalOffset = (scrollHost.ExtentHeight / listbox.Items.Count) * count + fromVerticalOffset;

if (ScrollViewer.GetHorizontalScrollBarVisibility(listbox) != ScrollBarVisibility.Disabled)
{
DoubleAnimation animation = new DoubleAnimation(fromHorizontalOffset, toHorizontalOffset, new TimeSpan(0, 0, 0, 0, 800), FillBehavior.HoldEnd);
scrollHost.BeginAnimation(ListBoxExtention.HorizontalOffsetProperty, animation);
}
if (ScrollViewer.GetVerticalScrollBarVisibility(listbox) != ScrollBarVisibility.Disabled)
{
DoubleAnimation animation = new DoubleAnimation(fromVerticalOffset, toVerticalOffset, new TimeSpan(0, 0, 0, 0, 800), FillBehavior.HoldEnd);
scrollHost.BeginAnimation(ListBoxExtention.VerticalOffsetProperty, animation);
}
}
}

public static void ScrollSkip_Double(this ListBox listbox, Double count)
{
ScrollViewer scrollHost = VisualTreeHelper.GetChild(listbox, 0) as ScrollViewer;
for (DependencyObject obj2 = listbox; obj2 != null; obj2 = VisualTreeHelper.GetChild(obj2, 0))
{
ScrollViewer viewer = obj2 as ScrollViewer;
if (viewer != null)
{
scrollHost = viewer;
break;
}
}
if (scrollHost != null && scrollHost.IsLoaded)
{
double fromHorizontalOffset = scrollHost.HorizontalOffset;
double toHorizontalOffset = 0.0;
double fromVerticalOffset = scrollHost.VerticalOffset;
double toVerticalOffset = 0.0;
toHorizontalOffset = (scrollHost.ExtentWidth / listbox.Items.Count) * count + fromHorizontalOffset;
toVerticalOffset = (scrollHost.ExtentHeight / listbox.Items.Count) * count + fromVerticalOffset;

if (ScrollViewer.GetHorizontalScrollBarVisibility(listbox) != ScrollBarVisibility.Disabled)
{
DoubleAnimation animation = new DoubleAnimation(fromHorizontalOffset, toHorizontalOffset, new TimeSpan(0, 0, 0, 0, 800), FillBehavior.HoldEnd);
scrollHost.BeginAnimation(ListBoxExtention.HorizontalOffsetProperty, animation);
}
if (ScrollViewer.GetVerticalScrollBarVisibility(listbox) != ScrollBarVisibility.Disabled)
{
DoubleAnimation animation = new DoubleAnimation(fromVerticalOffset, toVerticalOffset, new TimeSpan(0, 0, 0, 0, 800), FillBehavior.HoldEnd);
scrollHost.BeginAnimation(ListBoxExtention.VerticalOffsetProperty, animation);
}
}
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: