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的目的是为了最大限度地降低了 ...
随机推荐
- emmet 太 hackble 了 。。。
http://www.open-open.com/lib/view/open1451954899292.html
- java web 学习 --第四天(Java三级考试)
第三天的学习内容:http://www.cnblogs.com/tobecrazy/p/3453041.html jsp内置对象 out out 属性类型:JspWriter 作用域:page 作用: ...
- ABAP 内表的行列转换
http://www.cnblogs.com/qlp1982/p/3370591.html
- Effective C++ -----条款47:请使用traits classes表现类型信息
Traits classes使得“类型相关信息”在编译期可用.它们以template和“templates特化”完成实现. 整合重载技术(overloading)后,traits classes有可能 ...
- windows服务
.net windows 服务创建.安装.卸载和调试 原文:http://www.cnblogs.com/hfliyi/archive/2012/08/12/2635290.html 我对例子做了 ...
- 【HOG】
http://blog.csdn.net/masibuaa/article/details/12917961 把这份资料大概看完了 大概了解Hog了
- C# 串口操作系列(2) -- 入门篇,为什么我的串口程序在关闭串口时候会死锁 ?
第一篇文章我相信很多人不看都能做的出来,但是,用过微软SerialPort类的人,都遇到过这个尴尬,关闭串口的时候会让软件死锁.天哪,我可不是武断,算了.不要太绝对了.99.9%的人吧,都遇到过这个问 ...
- HTML标记语法之图片Img元素
语法:<img src=”xxx.jpg”alt=”xxx”title=”xxx”> 属性可取值如下: 属性名称 属性值 说明 src URL 图片路径 alt 文本 图片无法显示时的文本 ...
- August 18th 2016 Week 34th Thursday
Comedy is acting out optimism. 喜剧就是将乐观演绎出来. Being optimistic or pessimistic, that is all about your ...
- 让chrome的控制台更高大上(装B用)
作为一名屌丝前端程序员,在装B的道路上是越走越远了!废话不多说,直接先上几张图:我的Element是这样的: 我的console是这个样子的: 我的Timeline是这个样子的: ---------- ...