WPF MVVM模式下实现ListView下拉显示更多内容
在手机App中,如果有一个展示信息的列表,通常会展示很少一部分,当用户滑动到列表底部时,再加载更多内容。这样有两个好处,提高程序性能,减少网络流量。这篇博客中,将介绍如何在WPF ListView中实现这个功能。
实现思路:为ListView新增一个附加属性,用来绑定当下拉到底部时触发增加列表内容的功能。
XAML:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>
<Grid>
<ListView ItemsSource="{Binding Items}" Height="150" Width="80" local:ScrollViewerMonitor.AtEndCommand="{Binding FetchMoreDataCommand}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView> <UserControl Opacity=".85" Background="Gray" Height="150" Width="80" Visibility="{Binding Busy, Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock Text="Loading..." Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</UserControl>
</Grid>
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<ScrollViewer>(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<T>(DependencyObject root) where T : class
{
var queue = new Queue<DependencyObject>();
queue.Enqueue(root); while (queue.Count > )
{
DependencyObject current = queue.Dequeue();
for (int i = VisualTreeHelper.GetChildrenCount(current) - ; <= 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(); App.Current.Dispatcher.BeginInvoke(new Action(()=> { AddMoreItems(); Busy = false; }));
});
});
} private void AddMoreItems()
{
int start = items.Count;
int end = start + ;
for (int i = start; i < end; i++)
{
items.Add("Item " + i);
}
} readonly DelegateCommand fetchMoreDataCommand; public ICommand FetchMoreDataCommand
{
get
{
return fetchMoreDataCommand;
}
} private ObservableCollection<string> items = new ObservableCollection<string>(); public ObservableCollection<string> 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。
运行效果:

感谢您的阅读!代码点击这里下载。
WPF MVVM模式下实现ListView下拉显示更多内容的更多相关文章
- wpf mvvm模式下CommandParameter传递多参
原文:wpf mvvm模式下CommandParameter传递多参 CommandParameter一般只允许设置一次,所以如果要传递多参数,就要稍微处理一下.我暂时还没找到更好的方案,下面介绍的这 ...
- WPF MVVM模式的一些理解
/*本文转自 http://www.cnblogs.com/sirkevin/archive/2012/11/28/2793471.html */ 使用WPF+Mvvm开发一年多,期间由于对Mvvm模 ...
- WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍
WPF自学入门(十一)WPF MVVM模式Command命令 在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式 ...
- WPF MVVM模式中,通过命令实现窗体拖动、跳转以及显隐控制
原文:WPF MVVM模式中,通过命令实现窗体拖动.跳转以及显隐控制 在WPF中使用MVVM模式,可以让我们的程序实现界面与功能的分离,方便开发,易于维护.但是,很多初学者会在使用MVVM的过程中遇到 ...
- 解决boostrap中,iframe渲染下,苹果手机横向无法显示剩余内容问题
描述: 问题解决了,采用的手势拖动显示剩余内容,并不是有了横向滚动条 在head标签中加入 <head> <meta charset="utf-8"> &l ...
- [WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口
原文:[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口 [WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口 周银辉 现象: 大家可以试试下面这个很有趣但会带来Defect的现象:当我 ...
- WPF MVVM模式下的无阻塞刷新探讨
很多时候我们需要做一个工作,在一个方法体里面,读取大数据绑定到UI界面,由于长时间的读取,读取独占了线程域,导致界面一直处于假死状态.例如,当应用程序开始读取Web资源时,读取的时效是由网络链路的速度 ...
- WPF MVVM模式下ComboBox级联效果 选择第一项
MVVM模式下做的省市区的级联效果.通过改变ComboBox执行命令改变市,区. 解决主要问题就是默认选中第一项 1.首先要定义一个属性,继承自INotifyPropertyChanged接口.我这里 ...
- WPF自学入门(十一)WPF MVVM模式Command命令
在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式.正如上一篇文章中在开始说的,MVVM的目的是为了最大限度地降低了 ...
随机推荐
- PHP 面向对象:抽象类继承抽象类
抽象类继承另外一个抽象类时,不用重写其中的抽象方法.抽象类中,不能重写抽象父类的抽象方法.这样的用法,可以理解为对抽象类的扩展. 下面的例子,演示了一个抽象类继承自另外一个抽象类时,不需要重写其中的抽 ...
- java切换VPN让你像幽灵一样出现在全国各地
在很多情况下,有些网络应用的需求会要求模拟人在不同地区访问网站和应用.因而切换IP也就应运而生了,然而IP作为一种稀缺资源不是随便可以获得的.因而会想到应用程序切换VPN来达到全国不同地区访问网络.因 ...
- php xdebug配置
2015年11月27日 17:08:54 [xdebug] ;用触发的形式去开启跟踪调试 get/post/cookie 中添加变量"XDEBUG_TRACE" xdebug.au ...
- Linux下安装Flask开发框架
Flask是开发pythonweb的一个轻量级框架,适合初学者使用,当有了熟练的web基础后,再继续学习高级框架的开发,Linux一般安装好之后都会有python开发环境,给开发带来方便,下面是Fla ...
- ACM/ICPC 之 数据结构-邻接表+BFS(TSH OJ-无线广播Broadcast)
这道题中若能够构成互不干扰的区域,其构成的图其实就是汉密尔顿路(Hamilton road),因此如果能够观察出来可以直接转化为汉密尔顿路的存在性证明,即便不能观察,我相信ACMer也能转化为BFS问 ...
- MongoDB 分片的原理、搭建、应用
一.概念: 分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程.将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载.基本思想就是将集合切成小块,这 ...
- SqlDateTime 溢出。
SqlDateTime 溢出.必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM 之间 解决方法:不要怀疑自己的判断就是数据库字段里的datatime ...
- Python:IDLE清屏
清屏很简单,为IDLE增加一个清屏的扩展ClearWindow即可. 首先下载clearwindow.py(点击可直接下载,不能下载的可以右键保存,格式为py结尾), 将这个文件放到Python安装目 ...
- HDU 4945 2048(dp)
题意:给n(n<=100,000)个数,0<=a[i]<=2048 .一个好的集合要满足,集合内的数可以根据2048的合并规则合并成2048 .输出好的集合的个数%998244353 ...
- 【XLL API 函数】xlCoerce
将 XLOPER/XLOPER12 转换为另一种类型,或是查询表格中的单元格值. 函数原型 Excel12(xlCoerce, LPXLOPER12 pxRes, 2, LPXLOPER12 pxSo ...