使用依赖属性实现监视ListBox滚动到底部
发布时间:2020-12-13 19:43:38 所属栏目:百科 来源:网络整理
导读://自定义依赖属性用来监视ListBox滚动到底事件 public class ListBoxScrollToBottomNotify { public static ICommand GetScrollToBottomCommand(DependencyObject obj) { return (ICommand)obj.GetValue(ScrollToBottomCommandProperty); } public static vo
//自定义依赖属性用来监视ListBox滚动到底事件 public class ListBoxScrollToBottomNotify { public static ICommand GetScrollToBottomCommand(DependencyObject obj) { return (ICommand)obj.GetValue(ScrollToBottomCommandProperty); } public static void SetScrollToBottomCommand(DependencyObject obj,ICommand value) { obj.SetValue(ScrollToBottomCommandProperty,value); } //滚动到底问时响应的事件 public static readonly DependencyProperty ScrollToBottomCommandProperty = DependencyProperty.RegisterAttached("ScrollToBottomCommand",typeof(ICommand),typeof(ListBoxScrollToBottomNotify),new PropertyMetadata(null,OnCommandChanged)); static void OnCommandChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) { ListBox lb = d as ListBox; if (lb != null) { //确定只绑定一次ListBox的Loaded事件 if (e.OldValue == null) { lb.Loaded += new RoutedEventHandler(OnListBoxLoaded); } } } static void OnListBoxLoaded(object sender,RoutedEventArgs e) { ListBox lb = sender as ListBox; ScrollViewer scrollViewer = FindChildOfType<ScrollViewer>(lb); if (scrollViewer != null) { VerticalOffsetOfScrollViewNotify monitorVO = new VerticalOffsetOfScrollViewNotify(); monitorVO.Attached(scrollViewer); monitorVO.VerticalOffsetChanged = () => { double verticalOffset = Math.Round(scrollViewer.VerticalOffset); double scrollableHeight = Math.Round(scrollViewer.ScrollableHeight); if (verticalOffset >= scrollableHeight) { ICommand command= GetScrollToBottomCommand(lb); command.Execute(null); } }; } } //获取子类型 static T FindChildOfType<T>(DependencyObject root) where T : class { var queue = new Queue<DependencyObject>(); queue.Enqueue(root); while (queue.Count > 0) { DependencyObject current = queue.Dequeue(); for (int i = VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--) { var child = VisualTreeHelper.GetChild(current,i); var typedChild = child as T; if (typedChild != null) { return typedChild; } queue.Enqueue(child); } } return null; } } //监测ListBox中ScrollView的VerticalOffset改变 public class VerticalOffsetOfScrollViewNotify { //通过监控ListBox的MouseMove事件和ManipulationCompleted事件的效果并不好,//当手指在屏幕上划动后ListBox会因为惯性,再滚动一段距离.这样使用前两个事件就不能判断滚动的最后位置 //现在改成通过依赖属性绑定到ListBox的ScrollView的VerticalOffset来实现 DependencyProperty VerticalOffsetProperty; public VerticalOffsetOfScrollViewNotify() { VerticalOffsetProperty = DependencyProperty.RegisterAttached("VerticalOffset",typeof(double),typeof(VerticalOffsetOfScrollViewNotify),new PropertyMetadata(OnVerticalOffsetChanged)); } public void OnVerticalOffsetChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) { if (VerticalOffsetChanged != null) { VerticalOffsetChanged(); } } public Action VerticalOffsetChanged { get; set; } public void Attached(FrameworkElement ele) { if (ele != null) { ScrollViewer scrollViewer = ele as ScrollViewer; Binding binding = new Binding("VerticalOffset") { Source = scrollViewer }; scrollViewer.SetBinding(VerticalOffsetProperty,binding); } } }稍后添加注释. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |