gridcontrol 图片列异步加载

在gridview中指定一列,将ColumnEdit设置成pictureEdit

在使用showDialog这里窗体后,需要frm.Dispose()将资源释放

1.将该列的UnboundType属性设置为bound(默认值)以外的数据类型

2.为该列设置一个窗体内全局唯一的FieldName,这个FieldName不能是窗体中绑定数据源的的列,否则不会触发绑定事件

3.处理CustomUnboundColumnData事件

            gridView1.CustomUnboundColumnData += (s, e) => {
                if (e.Column.Name == colImg1.Name)
                {
                    //Console.WriteLine(colImg1.Name + ":" +DateTime.Now);
                    var it = e.Row as Q_SymptomRepositoryItem;
                    if (ImgDic.ContainsKey(it.Img1))
                    {
                        e.Value = ImgDic[it.Img1];
                    }
                    else
                    {
                        e.Value = XFormExtension.LoadingImgLazy.Value;
                    }
                }
            };

4.加载数据时启动图片异步下载,完成后使用SyncContext.Post刷新gridview

        private void LoadImageSync(List<Q_SymptomRepositoryItem> list)
        {
            var imgList = list;
            ThreadPool.QueueUserWorkItem((o) =>
            {
                using (WebClient wc = new WebClient())
                {
                    for (int i = 0; i < imgList.Count; i++)
                    {
                        var item = imgList[i];
                        try
                        {

                            if (string.IsNullOrWhiteSpace(item.Img1)) continue;
                            var bytes = wc.DownloadData(@"http://192.168.9.5:7111/getFile.ashx?rtype=repository&id=" + item.RecId);

                            using (var ms = new MemoryStream(bytes))
                            {
                                ImgDic[item.Img1] = XFormExtension.EnsureImage(Image.FromStream(ms));

                                if (!IsRunning) return;

                                SyncContext.Post((ox) =>
                                {
                                    gridView1.RefreshData();

                                }, null);
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("下载图片->" + ex.Message, "错误");
                        }

                    }
                }

            });
        }

5.完整代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;

namespace WinDetectionClockAdmin
{
    using DetectionClock.EFModel;
    using System.Collections.Concurrent;
    using System.Threading;
    using System.Net;
    using System.IO;
    using DevExpress.XtraGrid.Views.Grid.ViewInfo;
    using WinDetectionClock;

    public partial class frmSymptomRepositoryItem : DevExpress.XtraEditors.XtraForm
    {
        public GridControl MainGrid { get; set; }
        private SynchronizationContext SyncContext { get; set; }
        public Q_SymptomRepository SymptomRepository { get; set; }
        public bool IsRunning = false;

        private ConcurrentDictionary<string, Image> ImgDic = new ConcurrentDictionary<string, Image>();

        public frmSymptomRepositoryItem(Q_SymptomRepository repository):this()
        {
            SymptomRepository = repository;
            //加载数据
            LoadData();
        }
        public frmSymptomRepositoryItem()
        {
            InitializeComponent();
            MainGrid = gridControl1;
            SyncContext = SynchronizationContext.Current;
            this.StartPosition = FormStartPosition.CenterParent;

            #region 配置 gridControl 

            this.ConfigGrid(gridControl1, true);
            gridView1.CustomUnboundColumnData += (s, e) => {
                if (e.Column.Name == colImg1.Name)
                {
                    //Console.WriteLine(colImg1.Name + ":" +DateTime.Now);
                    var it = e.Row as Q_SymptomRepositoryItem;
                    if (ImgDic.ContainsKey(it.Img1))
                    {
                        e.Value = ImgDic[it.Img1];
                    }
                    else
                    {
                        e.Value = XFormExtension.LoadingImgLazy.Value;
                    }
                }
            };

            gridControl1.MouseDoubleClick += (s, e) =>
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    GridHitInfo hInfo = gridView1.CalcHitInfo(new Point(e.X, e.Y));
                    if (!hInfo.InRow) return; //确保点的是数据行而不是标头

                    var ent = qSymptomRepositoryItemBindingSource.Current as Q_SymptomRepositoryItem;
                    if (ent == null) return;

                    //hInfo.Column==null 标示点了行头
                    if (hInfo.Column!=null && hInfo.Column.Caption == "图片")
                    {

                            ////var img = gridView1.GetFocusedValue() as Image;
                            ////new frmPhotoDetail(img).ShowDialog();
                            ////return;

                    }

                    //双击其他标示修改
                    btnModify.PerformClick();

                }
            };
            gridControl1.MouseUp += (s, e) =>
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Right)
                {
                    GridHitInfo hInfo = gridView1.CalcHitInfo(new Point(e.X, e.Y));
                    if (hInfo.InRow)
                    {
                        var ent = qSymptomRepositoryItemBindingSource.Current as Q_SymptomRepositoryItem;
                        if (ent != null)
                        {
                            if (hInfo.Column != null && hInfo.Column.Caption == "图片")
                            {
                                popupMenu1.ShowPopup(Control.MousePosition);
                            }
                        }
                    }
                }
            };
            #endregion

            IsRunning = true;

        }
        #region 窗体关闭处理
        protected override void OnClosing(CancelEventArgs e)
        {
            IsRunning = false;
            base.OnClosing(e);
        }
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            ImgDic.ToList().ForEach(ent =>
            {
                ent.Value.Dispose();
            });
        }
        #endregion
        #region ToolBar Action

        private void LoadData()
        {
            using (var ctx = DBCtx.GetCtx())
            {
                var list= ctx.Q_SymptomRepositoryItem.Where(ent => ent.MainId == SymptomRepository.RecId).ToList();
                qSymptomRepositoryItemBindingSource.DataSource = list;

                #region 加载图片信息
                LoadImageSync(list);
                #endregion

            }
        }

        private void LoadImageSync(List<Q_SymptomRepositoryItem> list)
        {
            var imgList = list;
            ThreadPool.QueueUserWorkItem((o) =>
            {
                using (WebClient wc = new WebClient())
                {
                    for (int i = 0; i < imgList.Count; i++)
                    {
                        var item = imgList[i];
                        try
                        {

                            if (string.IsNullOrWhiteSpace(item.Img1)) continue;
                            var bytes = wc.DownloadData(@"http://192.168.9.5:7111/getFile.ashx?rtype=repository&id=" + item.RecId);

                            using (var ms = new MemoryStream(bytes))
                            {
                                ImgDic[item.Img1] = XFormExtension.EnsureImage(Image.FromStream(ms));

                                if (!IsRunning) return;

                                SyncContext.Post((ox) =>
                                {
                                    gridView1.RefreshData();

                                }, null);
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("下载图片->" + ex.Message, "错误");
                        }

                    }
                }

            });
        }

        private void btnAdd_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            var frm = new frmSymptomRepositoryItemEdit();
            frm.Owner = this;
            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                qSymptomRepositoryItemBindingSource.Add(frm.NewEnt);
                qSymptomRepositoryItemBindingSource.MoveLast();
                LoadImageSync(new List<Q_SymptomRepositoryItem>() { frm.NewEnt as Q_SymptomRepositoryItem });
            }
        }

        private void btnModify_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {

            var ent = qSymptomRepositoryItemBindingSource.Current as Q_SymptomRepositoryItem;

            if (ent == null) return;

            var old = this.Snapshoot<Q_SymptomRepositoryItem>(ent);

            var frm = new frmSymptomRepositoryItemEdit(ent);
            frm.Owner = this;
            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                qSymptomRepositoryItemBindingSource.ResetCurrentItem();

                LoadImageSync(new List<Q_SymptomRepositoryItem>() { ent });
            }
            else
            {
                this.Restore<Q_SymptomRepositoryItem>(old, ent);
            }

            //连续加载测试
            btnModify.PerformClick();
        }

        private void btnDel_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            try
            {
                var cur = qSymptomRepositoryItemBindingSource.Current as Q_SymptomRepositoryItem;
                if (cur == null) return;

                if (MessageBox.Show("您确定删除吗?", "警告", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
                {
                    using (var ctx = DBCtx.GetCtx())
                    {
                        var it = ctx.Q_SymptomRepositoryItem.FirstOrDefault(ent => ent.RecId == cur.RecId);
                        if (it != null)
                        {
                            ctx.DeleteObject(it);

                            ctx.SaveChanges();
                            qSymptomRepositoryItemBindingSource.Remove(cur);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnRefresh_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            LoadData();
        }

        private void btnFilter_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            this.ShowFilter();
        }
        #endregion

        private void btnViewImg_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            popupMenu1.HidePopup();
            var img = gridView1.GetFocusedValue() as Image;
            new frmPhotoDetail(img).ShowDialog();
            return;
        }

        private void frmSymptomRepositoryItem_Load(object sender, EventArgs e)
        {  

            var timer = new  System.Windows.Forms.Timer();
            timer.Interval = 100;
            timer.Tick += (s, ie) =>
            {
                timer.Enabled = false;
                this.Close();
            };
            timer.Start();
        }
    }
}

时间: 2024-07-28 15:31:28

gridcontrol 图片列异步加载的相关文章

Android开发之图片处理专题(三):利用ThreadPoolExcutor线程池实现多图片的异步加载

在上一篇专题Android开发之图片处理专题(二):利用AsyncTask和回调接口实现图片的异步加载和压缩中我们实现了listView的图片的大量加载.今天,我们换一种方式,采用线程池的方式来实现. 我们需要准备两个东西: 1.图片下载任务类 2.线程池. 1.图片下载任务类. 图片下载任务类,将需要显示的iamgeView,线程通讯消息管理者handler进行了封装.当图片下载无论成功还是失败,handler发送对应的消息,传入的iamgeView显示对应的图片.这里就不在应用软引用技术,采

Android开发之图片处理专题(二):利用AsyncTask和回调接口实现图片的异步加载和压缩

在上一篇专题Android开发之图片处理专题(一):利用软引用构建图片高速缓存中我们讲述了如何利用软引用技术构建高速缓存.那么想要用到图片,首先得有图片的来源.一般而言,一个应用的图片资源都是从服务器处获得的.今天,我们利用Android开发之网络请求通信专题(二):基于HttpClient的文件上传下载里面封装好的httpUtils来实现图片的下载,然后加载到本地配合软引用缓存使用,以一个listView为例子来说明. 一.准备工作 我们需要准备以下几个类(图片对象和软引用缓存类请参考上一篇专

图片高效加载(二) 图片的异步加载

图片的异步加载是利用AsynTask类对图像进行后台加载完成后再给ImageView,先转载一篇前人的较好的总结后面再添加一些自己的见解和贴上完整的实现demo. 前面的转自:https://my.oschina.net/rengwuxian/blog/183802 摘要: 有没有过这种体验:你在Android手机上打开了一个带有含图片的ListView的页面,用手猛地一划,就见那ListView嘎嘎地卡,仿佛每一个新的Item都是顶着阻力蹦出来的一样?看完这篇文章,你将学会怎样避免这种情况的发

WPF技术触屏上的应用系列(五): 图片列表异步加载、手指进行缩小、放大、拖动 、惯性滑入滑出等效果

原文:WPF技术触屏上的应用系列(五): 图片列表异步加载.手指进行缩小.放大.拖动 .惯性滑入滑出等效果 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系统,54寸大屏电脑电视一体机.要求有很炫的展示效果,要有一定的视觉冲击力,可触控操作.当然满足客户的要求也可以有其它途径.但鉴于咱是搞 .NET技术的,首先其冲想到的微软WPF方面,之前对WPF的了解与学习也只是停留在比较浅的层面,没有进一步深入学习与应用.所以在项目接来以后,也就赶鸭子上架了,经过努力

Android中图片的异步加载

转: 1.  为什么要异步加载图片 下载图片比较费时,先显示文字部分,让加载图片的过程在后台,以提升用户体验 2.  SoftReference的作用 栈内存—引用 堆内存—对象 Eg: Object obj = new Object(); Obj = null; 当垃圾收集器启动时,会回收对象: 当一个对象没有任何引用指向,就会被回收. SoftReference<Object>sr = new SoftReference<Object>(new Obnject()); 引用是软

Android下载图片 图片的异步加载 和缓存存取

一.创建异步任务 public class LoadBitmapAsyn extends AsyncTask<String,Void,Bitmap> { Context context; ImageView img; private HashMap<String,SoftReference<Bitmap>> imageCache=null; public LoadBitmapAsyn(ImageView img){ this.img=img; this.context=

实现图片的异步加载

图片异步加载功能是现在web中非常常见的一个针对web做优化的方法.尤其是在移动端,面对大量的图片列表的时候,如果没有做相应的优化,会直接导致页面滑动和加载的卡顿,而且用户会莫名的发现当前应用占用的流量会很大,因为他可能都没有浏览到很多图片,而程序就自动加载了所以的图片,对于一个流量吃紧的人来讲,这个也是很讨厌的.所以实现按浏览需求加载时十分有必要的. 其实实现图片异步加载的核心思路十分简单,就是通过判断当图片元素是否出现在视窗范围内后,则去加载图片资源,否则不加载.所以我们需要首先解决判断im

BitmapImage处理网络图片,例如阿里云获取的图片。异步加载到需要显示的控件上。提升速度非常明显。

想直接把网络图片赋给控件,又要下载又要缓存,速度非常慢.不流畅. 需要进行处理,异步加载会显著提升速度.方法如下: public static BitmapImage ByteArrayToBitmapImage(byte[] byteArray) { BitmapImage bmp = null; try { bmp = new BitmapImage(); bmp.BeginInit(); bmp.StreamSource = new MemoryStream(byteArray); bmp

今日头条图片ajax异步加载爬取,并保存至mongodb,以及代码写法的改进

import requests,time,re,json,pymongofrom urllib.parse import urlencodefrom requests.exceptions import RequestExceptionfrom bs4 import BeautifulSoup as bs #连接mongodbclient = pymongo.MongoClient(host='localhost',port=27017)#指定数据库名称db = client.toutiao #