public class MyListBox: ListBox
{
public MyListBox() : base()
{
AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(ScrollView_ScrollChanged), true);
}
#region 是否滚动到底部
private void ScrollView_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
if (e.OriginalSource is ScrollViewer scrollViewer)
{
var isBottom = ListBoxHelper.IsVerticalScrollBarAtButtom(scrollViewer);
SetIsScrolledBottom(this, isBottom);
}
}
/// <summary>
/// 判断ScrollViewer是否滚动到底部
/// </summary>
/// <param name="scrollViewer"></param>
/// <returns></returns>
public static bool IsScrolledToButtom(ScrollViewer scrollViewer)
{
var isBottom = false;
if (Math.Abs(scrollViewer.VerticalOffset) > 0)
{
if (scrollViewer.VerticalOffset + scrollViewer.ViewportHeight == scrollViewer.ExtentHeight)
{
isBottom = true;
}
}
if (scrollViewer.VerticalScrollBarVisibility == ScrollBarVisibility.Disabled
|| scrollViewer.VerticalScrollBarVisibility == ScrollBarVisibility.Hidden
|| scrollViewer.ScrollableHeight <= 0)
{
isBottom = true;
}
return isBottom;
}
public static readonly DependencyProperty IsScrolledBottomProperty = DependencyProperty.Register(
"IsScrolledBottom", typeof(bool), typeof(MyListBox), new PropertyMetadata(default(bool)));
public static void SetIsScrolledBottom(DependencyObject element, bool value)
{
element.SetValue(IsScrolledBottomProperty, value);
}
public static bool GetIsScrolledBottom(DependencyObject element)
{
return (bool)element.GetValue(IsScrolledBottomProperty);
}
#endregion
}
属性IsScrolledBottom,表示当前已经滚动到底部
PS:上面写法还是有点小问题。
当前列表没有触发滚动到底部后,往列表中添加数据,添加过程中并不会触发ScrollChanged。
然后属性IsScrolledBottom就不准确了。
解决:对ListBox.Items.CollectionChanged添加监听,在触发事件中,调用IsScrolledToButtom方法,主动获取并设置当前IsScrolledBottom属性