滚动条滑到底完美解决方案(适合任何带滚动条或ScrollBar控件 (一)

2014-11-24 02:32:53 · 作者: · 浏览: 7

看见很多人在求滚动条滑倒底部自动加载数据的解决方案,各种各样的方案很多,但令人满意的确没几个。在这里我分享一个我的自认为满意的解决方案。
首先说下大致原理:监视滚动条坐标的变化,在达到底部时触发自己的处理事件。
原理很简单,但实现起来可没这么容易,先上代码,边看边说。
[csharp]
public class ScrollViewerTrigger:TriggerBase
{
ScrollViewer ScrollView;
public static readonly DependencyProperty DirectionTypeProperty = DependencyProperty.Register("DirectionType", typeof(DirectionType), typeof(ScrollViewerTrigger), new PropertyMetadata(DirectionType.Bottom));

public DirectionType DirectionType
{
get
{
return (DirectionType)base.GetValue(ScrollViewerTrigger.DirectionTypeProperty);
}
set
{
base.SetValue(ScrollViewerTrigger.DirectionTypeProperty, value);
}
}

public event EventHandler ScrollTrigger;

public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.Register("VerticalOffset", typeof(double), typeof(ScrollViewerTrigger), new PropertyMetadata(0.0, new PropertyChangedCallback(VerticalOffsetPropertyChanged)));

public double VerticalOffset
{
get
{
return (double)base.GetValue(ScrollViewerTrigger.VerticalOffsetProperty);
}
set
{
base.SetValue(ScrollViewerTrigger.VerticalOffsetProperty, value);
}

}

public static void VerticalOffsetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var behavior = d as ScrollViewerTrigger;
if (behavior != null)
behavior.OnVerticalOffsetChanged();
}

protected override void OnAttached()
{

base.OnAttached();

if (this.AssociatedObject != null && this.AssociatedObject is FrameworkElement)
{
(this.AssociatedObject as FrameworkElement).SizeChanged += control_SizeChanged;
}
}

void control_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (this.AssociatedObject == null || !(this.AssociatedObject is FrameworkElement))
return;

ScrollViewer Scroll = this.AssociatedObject.GetFirstDescendantOfType();
if (Scroll != null)
{
AttachedScroll(Scroll);
(this.AssociatedObject as FrameworkElement).SizeChanged -= control_SizeChanged;
}
}

void AttachedScroll(ScrollViewer Scroll)
{
if (Scroll == null)
return;
ScrollView = Scroll;

Binding binding = new Binding();
binding.Source = Scroll;
binding.Path = new PropertyPath("VerticalOffset");

BindingOperations.SetBinding(this, ScrollViewerTrigger.VerticalOffsetProperty, binding);

}

void OnVerticalOffsetChanged()
{
ScrollViewer Scroll = ScrollView;
if (Scroll == null)
return;

switch (DirectionType)
{
case DirectionType.Top:
{
if (Scroll