zoukankan      html  css  js  c++  java
  • 利用WPF的ListView进行大数据量异步加载

         由于之前利用Winform的ListView进行大数据量加载的时候,诟病良多,所以今天试着用WPF的ListView来做了一下,结果没有让我失望,我将一个拥有43000行,510列的csv文件导入到了ListView中,总共耗时在10s左右,并且在导入的过程中,软件界面上的提示信息一直在提示当前导入了多少条。在整个导入的过程中没有感觉到ListView的闪烁。

         在测试大数据量加载的时候,我们有两件事情需要完成,第一个就是考虑到大数据量,我们得利用异步方式来进行,否则界面及其容易被阻塞住;第二个就是由于数据量过大,导入时间可能比较长,如何通知用户当前导入的进度。

         针对问题一,可以考虑利用委托的异步方式进行;针对问题二,可以考虑到线程和UI交互的方式。

         首先要说的是大数据量的导入,和WinForm不同的是,在导入数据到ListView之前,我们需要先将数据导入到一个DataTable中,然后利用GridView来处理DataTable,最后绑定即可,见代码流程:

            /// <summary>
    /// 开始对BindData函数进行异步处理
    /// </summary>
    private void BeginBindData()
    {
    ........
    }

    /// <summary>
    /// 对BindData函数进行异步处理完毕,向用户发送通知
    /// </summary>
    /// <param name="iar"></param>
    private void EndBindData(IAsyncResult iar)
    {
    ........
    }

    /// <summary>
    /// 考虑到BindData导入数据比较耗时,采用了BeginBindData来进行异步加载
    /// </summary>
    private void BindData()
    {
    ........
    }


    这就是整个异步加载方式的执行流程,下面见具体代码:

     #region Invoke the Binding Data method asynchorously

    /// <summary>
    /// 开始对BindData函数进行异步处理
    /// </summary>
    private void BeginBindData()
    {
    BindDataAsync bindData = new BindDataAsync(BindData);
    IAsyncResult iar = bindData.BeginInvoke(new AsyncCallback(EndBindData), bindData);
    tsStatus.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
    {
    tsStatus.Content = "正在加载中。。。";
    }));
    }

    /// <summary>
    /// 对BindData函数进行异步处理完毕,向用户发送通知
    /// </summary>
    /// <param name="iar"></param>
    private void EndBindData(IAsyncResult iar)
    {
    tsStatus.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
    {
    tsStatus.Content = "加载完毕。。。";
    }));
    BindDataAsync bindData = (BindDataAsync)iar.AsyncState;
    bindData.EndInvoke(iar);
    }

    /// <summary>
    /// 考虑到BindData导入数据比较耗时,采用了BeginBindData来进行异步加载
    /// </summary>
    private void BindData()
    {

    GetHeader();
    DataTable dt = LoadData();

    tsStatus.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
    {
    tsStatus.Content = "正在绑定数据,请稍候。。。";
    }));

    //using Dispatcher to avoid crossing thread exception
    listView1.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
    {

    foreach (DataColumn item in dt.Columns)
    {
    GridViewColumn gvc = new GridViewColumn();
    //设置行的绑定源
    gvc.DisplayMemberBinding = new Binding(item.ColumnName);
    //设置头部名称
    gvc.Header = item.ColumnName;
    gv.Columns.Add(gvc);
    }

    //设置显示方式,利用GridView来显示
    listView1.View = gv;
    //设置待绑定的上下文数据对象
    listView1.DataContext = dt;
    //绑定数据,不可缺少,否则导致绑定失败
    listView1.SetBinding(ListView.ItemsSourceProperty, new Binding());


    }));
    }
    #endregion


    其次,关于如何向用户发送通知,这个涉及到了线程和UI交互,在Winform中我们可以通过Control.InvokeRequired来判断是否需要进行交互,然后通过Invoke方法进行进一步处理,而在WPF中,则需要利用Dispacther来进行处理,也即:Control.Dispacter方法,在代码中,是这样做到的(拿名称为tsStatus的Label控件来说):

     tsStatus.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
    {
    tsStatus.Content = "当前已经加载"+count+"条数据。。。";
    }));

     

    在Action中用了匿名方法来实现,非常方便。

     源代码下载:点击这里下载

  • 相关阅读:
    JQueryMobile开发必须的知道的知识
    15款很棒的 JavaScript 开发工具
    浅谈 JavaScript 编程语言的编码规范
    也谈谈js的压缩,jquery压缩。【转】
    jQuery实现点击单选按钮切换选中状态效果
    JavaScript入门学习书籍的阶段选择
    试读《基于MVC的JavaScript Web富应用开发》— 不一样的JavaScript
    javaScript之function定义
    利用Powershell自动部署asp.net mvc网站项目 (一)
    【好文收藏】javascript中event对象详解
  • 原文地址:https://www.cnblogs.com/scy251147/p/2305319.html
Copyright © 2011-2022 走看看