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

2014-11-24 02:32:53 · 作者: · 浏览: 8
roll != 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.ScrollableHeight < double.Epsilon || Scroll.VerticalOffset > double.Epsilon)
return;
}
break;
case DirectionType.Bottom:
{
if (Scroll.ScrollableHeight < double.Epsilon || Scroll.VerticalOffset + Scroll.ExtentHeight - Scroll.ScrollableHeight < Scroll.ScrollableHeight)
return;
}
break;
case DirectionType.Left:
{
if (Scroll.ScrollableWidth < double.Epsilon || Scroll.HorizontalOffset > double.Epsilon)
return;
}
break;
case DirectionType.Right:
{
if (Scroll.ScrollableWidth < double.Epsilon || Scroll.HorizontalOffset < Scroll.ScrollableWidth)
return;
}
break;
default: break;
}

if (ScrollTrigger != null)
{
ScrollTrigger(this.AssociatedObject, new EventArgs());
}
base.InvokeActions(null);

}


protected override void OnDetaching()
{
base.OnDetaching();
}
} 整个实现是Trigger的扩展,这样灵活性和通用性非常高,不管是什么控件。因为Trigger本身是附加元素,对于任何控件都可以附加上去,不要要改动原有代码就可以实现功能扩展。Trigger自带的Actions则有很强的灵活性,动作触发后可以执行多个Action.
DirectionType是触发方向,分上下左右4个方向,默认是在底部触发,想做下拉刷新功能时把DirectionType改成Top就可以了了。
VerticalOffset则是实现滚动条监视的关键,什么作用稍后说明。
OnAttached()是整个Trigger的入口,在这里面我监控了一个通用事件SizeChanged,主要是通过这个事件查找控件内的ScrollViewer控件。这里不能使用loaded事件,因为有些带滚动条的控件是在加载元素时才建立ScrollViewer控件,loaded事件触发时内部元素不一定会被加载,而 SizeChanged触发时ScrollViewer已经建立好了。
control_SizeChanged中关键语句在于 this.AssociatedObject.GetFirstDescendantOfType();这语句是从当前控件的子控件中查找ScrollViewer控件,查找到后就会调用AttachedScroll对ScrollViewer的滚动进行监视。
下面就是关键了,AttachedScroll函数要对ScrollViewer进行监控,那么如何监控呢?
[csharp]
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 AttachedScroll(ScrollViewer Scroll)
{
if (Scroll == null)
return;
ScrollView = Scroll;

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