最近公司在做一个Windows项目,其中主界面需要实时更新数据,大概是0.5秒刷一次数据。一开始想用winform做的,思路是使用winform把界面画出来然后显示。但是觉得比较复制而且麻烦,后来查看了网上资料,感觉使用wpf就不用那么麻烦,而且代码都比较少而且清晰,而且支持更改数据就能刷新界面,决定试验一把。
网上关于listview的资料不少,但是都是片面的,或者不全。
好了,现在开始,新建wpf项目,添加用户控件,在用户控件里添加listview控件,并添加数据模板。
定义数据模型:public class DataModelValueList : ObservableCollection<DataModelValue>{}public class DataModelValue : INotifyPropertyChanged
{public event PropertyChangedEventHandler PropertyChanged;public int ID { get; set; }private string no;public string No{get { return no; }set{if (no != value){no = value;if (this.PropertyChanged != null){this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("No"));}}}}private string name;public string Name{get { return name; }set{if (name != value){name = value;if (this.PropertyChanged != null){this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));}}}}private string v;public string V{get { return v; }set{if (v != value){v = value;if (this.PropertyChanged != null){this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("V"));}}}}private string i;public string I{get { return i; }set{if (i != value){i = value;if (this.PropertyChanged != null){this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("I"));}}}}private string c;public string C{get { return c; }set{if (c != value){c = value;if (this.PropertyChanged != null){this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("C"));}}}}private string t;public string T{get { return t; }set{if (t != value){t = value;if (this.PropertyChanged != null){this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("T"));}}}}
}

然后给用户控件添加属性:

    private DataModelValueList dataModelValueList;public DataModelValueList DataModelValueList{get { return dataModelValueList; }set{dataModelValueList = value;lv.ItemsSource = dataModelValueList;}}

给该属性赋值的时候会自动更新界面,注意,只有数据更改才会刷新,而且是局部刷新。
在主界面窗体添加:

修改主窗体类如下:
public MainWindow()
{
InitializeComponent();

        InitialListViewData();var userControl1 = new UserControl1();userControl1.DataModelValueList = dataModelValueList;listViewContainer.Children.Add(userControl1);Task.Factory.StartNew(Begin);}private static DataModelValueList dataModelValueList = new DataModelValueList();private readonly TaskScheduler _syncContextTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();private readonly TaskScheduler _syncContextTaskSchedulerTest = TaskScheduler.FromCurrentSynchronizationContext();private static int count = 1;private static int totalCount = 512 * 2;private static int initialCompletedCount = 0;private void InitialListViewData(){var temp = "0";for (var i = 0; i < 1024; i++){dataModelValueList.Add(new DataModelValue() { ID = i, No = temp, Name = temp, C = temp, V = temp, I = temp, T = temp }); ;}}private void Begin(){while (true){Thread.Sleep(500);Task.Factory.StartNew(() => RefreshData(), new CancellationTokenSource().Token, TaskCreationOptions.None, _syncContextTaskScheduler).Wait();}}private void RefreshData(){//return;count += 1;var temp = count.ToString();for (var i = 0; i < totalCount; i++){dataModelValueList[i].Name = temp;dataModelValueList[i].No = temp;dataModelValueList[i].C = temp;dataModelValueList[i].I = temp;dataModelValueList[i].T = temp;dataModelValueList[i].V = temp;}}

程序运行起来后如图:
要是操作一下,比如拉动滚动条,感觉有点卡顿,因为是刷新全部数据,1024个数据,要是数据更多,比如几千个,那会更卡。
怎么办?
能不能只刷新屏幕可见范围内的数据?因为屏幕可见数据也就几十个,相比刷新1000个,那就太好了!相干就干!
首先要获取到屏幕第一个可见数据,然后根据每个数据的长宽就可以计算出可见屏幕里装的数据。到网上搜获取listview可见数据,好像没有完整方案,只查到获取第一个可见数据的,这就离成功不远了啊。
在用户控件里增加代码:

    public Tuple<int, int> Test(){int startIndex = -1;int endIndex = -1;HitTestResult hitTest = VisualTreeHelper.HitTest(lv, new Point(5, 5));System.Windows.Controls.ListViewItem item = GetListViewItemFromEvent(null, hitTest.VisualHit) as System.Windows.Controls.ListViewItem;startIndex = ((DataModelValue)item.DataContext).ID;endIndex = startIndex;endIndex += (int)Math.Ceiling((lv.ActualWidth / item.ActualWidth + 1) * (lv.ActualHeight / item.ActualHeight + 1));return new Tuple<int, int>(startIndex, endIndex);}System.Windows.Controls.ListViewItem GetListViewItemFromEvent(object sender, object originalSource){DependencyObject depObj = originalSource as DependencyObject;if (depObj != null){// go up the visual hierarchy until we find the list view item the click came from  // the click might have been on the grid or column headers so we need to cater for this  DependencyObject current = depObj;while (current != null && current != lv){System.Windows.Controls.ListViewItem ListViewItem = current as System.Windows.Controls.ListViewItem;if (ListViewItem != null){return ListViewItem;}current = VisualTreeHelper.GetParent(current);}}return null;}

然后主界面修改更新数据函数:
private void RefreshData()
{
var a = ((UserControl1)listViewContainer.Children[0]).Test();
//return;
count += 1;
var temp = count.ToString();

        for (var i = 0; i < totalCount; i++){if (i < a.Item1 || a.Item2 < i){continue;}dataModelValueList[i].Name = temp;dataModelValueList[i].No = temp;dataModelValueList[i].C = temp;dataModelValueList[i].I = temp;dataModelValueList[i].T = temp;dataModelValueList[i].V = temp;}}

然后程序跑起来,现在随便拖拉滚动条,也不卡顿了,万岁!
最后,要是数据量很大,比如几千条,那么程序启动的时候就会比较慢,有可能需要一段时间,比如20秒,这个感觉也不大好,因为启动这段时间里,界面是空白的,用户会任务程序死掉了。解决办法是:启动时,开启一个新的线程,然后定时加载数据,比如每隔3秒加载500条数据,如果总共是5000条,那么就要加载30秒,程序启动过程中就能看到数据,而且滚动条会不断变短,但是还是会有点卡,没办法啦。等加载完数据就不卡了。
最后呈上代码:
链接:https://pan.baidu.com/s/1KgoC5nSzQCpZ1m4cb_ZaYA
提取码:1234

wpf listview 大数据界面刷新相关推荐

  1. C#中WPF ListView绑定数据的实例详解

    C#中WPF ListView绑定数据的实例详解 发布时间: 2019-03-09 19:29:46 来源: 互联网 作者: 晨曦888 栏目: C#教程 点击: 298 这篇文章主要介绍了C#中WP ...

  2. wpf 大数据界面_24小时删!WPF 界面开发可视化数据源500行代码分享

    通过DevExpress WPF Controls,您能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案. 在本教程中,您将完成可视化数据 ...

  3. Android ListView优化之局部刷新(非notifyDataSetChanged()方式)

    ListView是在Android开发中用得非常多的控件之一,并且这些列表还经常需要我们去对listView的数据进行刷新操作,在这种情况下,我们往往都会去调用adapter的notifyDataSe ...

  4. php查询mysql表里的数据_PHP/MYSQL 查询大数据/遍历表

    PHP:PHP 5.3.6 (cli) (built: Jun 15 2011 16:29:50) MYSQL:5.1.51 如果我们有的一张表有几百万或几千万的记录,我们要使用 PHP 将所有的记录 ...

  5. (转)利用WPF的ListView进行大数据量异步加载

    原文:http://www.cnblogs.com/scy251147/archive/2012/01/08/2305319.html 由于之前利用Winform的ListView进行大数据量加载的时 ...

  6. Qt编写数据可视化大屏界面电子看板12-数据库采集

    一.前言 数据采集是整个数据可视化大屏界面电子看板系统核心功能,没有数据源,这仅仅是个玩具UI,没啥用,当然默认做了定时器模拟数据,产生随机数据,这个可以直接配置文件修改来选择采用何种数据采集方法,总 ...

  7. Qt编写数据可视化大屏界面电子看板系统

    一.前言 目前大屏大数据可视化UI这块非常火,趁热也用Qt来实现一个,Qt这个一站式超大型GUI超市,没有什么他做不了的,大屏电子看板当然也不在话下,有了QSS和QPainter这两个无敌的工具组合, ...

  8. Qt编写数据可视化大屏界面电子看板1-布局方案

    一.前言 布局方案在整个数据可视化大屏界面电子看板系统中,是除了基础功能以外的核心功能之一,只有具备了布局方案这个功能,才能让用户随意调整自己想要的布局,保存成自定义名称的布局配置文件,这样就大大增加 ...

  9. Python之GUI:基于Python的GUI界面设计的一套AI课程学习(机器学习、深度学习、大数据、云计算等)推荐系统(包括语音生成、识别等前沿黑科技)

    Python之GUI:基于Python的GUI界面设计的一套AI课程学习(机器学习.深度学习.大数据.云计算等)推荐系统(包括语音生成.识别等前沿黑科技) 导读 基于Python的GUI界面设计的一套 ...

  10. 程序图形化界面刷新以及如何从tkinter窗口中正确读出数据

    1.问题提出 在做图形化编程时经常遇到界面刷新函数,如python tkinter中的mainloop,java线程new和remove并用等等.但是想要使用图形化界面的数据(输入的文本数据或其他)时 ...

最新文章

  1. 简单创建vsftp server
  2. 连接查询,结构、循环语句
  3. mysql提示太多连接_mysql数据库提示连接太多怎么办
  4. 回答知乎问题:你写过什么自认为惊艳的诗?
  5. 复制中含有非法字符导致的错误
  6. git回退历史版本无法上传_Git系列教程(二):版本库中添加文件、版本回退
  7. OC 内存管理黄金法则
  8. 【算法与数据结构】哈希表-链地址法
  9. 电影院订票选座小程序 开题报告
  10. 群晖京东云对象存储_干货 | 基于Go SDK操作京东云对象存储OSS的入门指南
  11. 天眼查是怎么获得企业工商信息的?
  12. 【python】迭代器与生成器到底是什么?看完你就知道
  13. linux添加 usr bin,Linux基础之/bin、 /sbin、/ usr/bin,、/usr/sbin的用处
  14. 【HCNP-OSPF】LSA
  15. 历届蓝桥杯Scratch编程省赛 初级 中级 青少年编程比赛省赛真题解析【持续更新 已更新至35题】
  16. 归并排序及“归并”思想的应用
  17. 网站关键词怎么布局才更合理?
  18. Python3中小括号()、中括号[]、花括号{}的区别
  19. 2021牛客寒假算法基础集训营1 E.三棱锥之刻
  20. 写给一个外汇女交易员的信(连载一)

热门文章

  1. CAS单点登录原理解析
  2. leetcode 合并两个有序数组
  3. 2020云课堂智慧职教答案计算机,2020云课堂智慧职教答案英语,云智慧职教题库,智慧职教测试答案...
  4. 油库蓝牙+北斗RTK人员定位方案解析
  5. Navicat Premium 12.0.29中文版64位+破解补丁
  6. 移动警务系统建设方案
  7. 数据分析:SWOT分析法
  8. WPS/Word参考文献格式规范及引用的方法
  9. python中jieba库安装中出现pip库需要更新怎么办_python安装jieba库
  10. Linux下安装Eclipse的PHP插件(PHPEclipse)