博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF MVVM模式下实现ListView下拉显示更多内容
阅读量:6693 次
发布时间:2019-06-25

本文共 5108 字,大约阅读时间需要 17 分钟。

在手机App中,如果有一个展示信息的列表,通常会展示很少一部分,当用户滑动到列表底部时,再加载更多内容。这样有两个好处,提高程序性能,减少网络流量。这篇博客中,将介绍如何在WPF ListView中实现这个功能。

实现思路:为ListView新增一个附加属性,用来绑定当下拉到底部时触发增加列表内容的功能。

XAML:

ScrollViewerMonitor:

public class ScrollViewerMonitor    {        public static ICommand GetAtEndCommand(DependencyObject obj)        {            return (ICommand)obj.GetValue(AtEndCommandProperty);        }        public static void SetAtEndCommand(DependencyObject obj, ICommand value)        {            obj.SetValue(AtEndCommandProperty, value);        }        public static readonly DependencyProperty AtEndCommandProperty =            DependencyProperty.RegisterAttached("AtEndCommand", typeof(ICommand),                 typeof(ScrollViewerMonitor), new PropertyMetadata(OnAtEndCommandChanged));        public static void OnAtEndCommandChanged(            DependencyObject d, DependencyPropertyChangedEventArgs e)        {            FrameworkElement element = (FrameworkElement)d;            if (element != null)            {                element.Loaded -= element_Loaded;                element.Loaded += element_Loaded;            }        }        private static void element_Loaded(object sender, RoutedEventArgs e)        {            FrameworkElement element = (FrameworkElement)sender;            element.Loaded -= element_Loaded;            ScrollViewer scrollViewer = FindChildOfType
(element); if(scrollViewer == null) { throw new InvalidOperationException("ScrollViewer not found."); } scrollViewer.ScrollChanged += delegate { bool atBottom = scrollViewer.VerticalOffset >= scrollViewer.ScrollableHeight; if(atBottom) { var atEnd = GetAtEndCommand(element); if(atEnd != null) { atEnd.Execute(null); } } }; } private static T FindChildOfType
(DependencyObject root) where T : class { var queue = new Queue
(); 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; } }

MainViewModel:

public class MainViewModel : INotifyPropertyChanged    {        public MainViewModel()        {            _busy = false;            AddMoreItems();            fetchMoreDataCommand = new DelegateCommand(() => {                ThreadPool.QueueUserWorkItem(                    delegate                    {                        Busy = true;                        Thread.Sleep(3000);                        App.Current.Dispatcher.BeginInvoke(new Action(()=> {                            AddMoreItems();                            Busy = false;                        }));                    });            });        }        private void AddMoreItems()        {            int start = items.Count;            int end = start + 10;            for (int i = start; i < end; i++)            {                items.Add("Item " + i);            }        }        readonly DelegateCommand fetchMoreDataCommand;        public ICommand FetchMoreDataCommand        {            get            {                return fetchMoreDataCommand;            }        }        private ObservableCollection
items = new ObservableCollection
(); public ObservableCollection
Items { get { return items; } } private bool _busy; public bool Busy { get { return _busy; } set { if(_busy != value) { _busy = value; OnPropertyChanged("Busy"); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if(PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }

Busy属性用来决定是否显示Loading。

运行效果:

感谢您的阅读!代码点击下载。

转载于:https://www.cnblogs.com/yang-fei/p/4718325.html

你可能感兴趣的文章
Windows App开发之集合控件与数据绑定
查看>>
AMD、CMD/AMD与CMD的区别
查看>>
Python~第一天
查看>>
Linux管理用户账号
查看>>
redis中使用lua脚本
查看>>
颜色数组
查看>>
ELASTICSEARCH清理过期数据
查看>>
oo第三次博客作业
查看>>
设计模式六大原则(转载)
查看>>
Delphi TMemoryStream写入到字符串和字符串写入到流
查看>>
C#判断操作系统是32位还是64位(转)
查看>>
WebADI_配置设定01_设定整合WebADI Integrator(案例)
查看>>
GL_Oracle Erp常用的报表(汇总)
查看>>
使用javacv,解码socket接收的H264码流(byte[]),转为yuv处理,最后再合成转为H264...
查看>>
长春理工大学第十四届程序设计竞赛(重现赛)I
查看>>
corosync+pacemaker部署高可用集群
查看>>
利用Fidder工具抓取App数据包
查看>>
jQuery中 prop 与 attr 方法的区别
查看>>
jsp中遇到Integer的方法valueOf()和parseInt()的区别.前者要求是对象类型,后者是数字型字符串...
查看>>
java实例三维空间求点之间的距离。。。。
查看>>