Devexpress 表格GridView列RepositoryItemPictureEdit异步加载远程URL图片
需求
DevExpress 表格中有一列PictureEdit,数据源中有一个图片URL字段,需要把URL的图片显示出来,
使用异步多线程加载图片,提高图片加载速度,并且图片加载过程中不影响界面操作

解决方案
创建类库:AsynDownImage.cs
/// <summary> /// GridView异步加载url地址的图片,通知CustomColumnDataEventArgs参数 /// </summary> public class AsynDownImage { private string _URL { get; set; } private Bitmap _Image { get; set; } private bool _IsReady = false; private object _Locker = new object(); private List<DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs> _listens; private bool _UseLocalImage = true;//使用本地缓存图片 public AsynDownImage(string url) { _UseLocalImage = true; _URL = url; _listens = new List<DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs>(); this.StartDown(); } /// <summary> /// 开始加载图片 /// </summary> void StartDown() { /* //判断本地缓存文件 if (_UseLocalImage && ImageFileCache.Instance.Exists(ImageBuckleName.small_images, this._URL)) { this._Image = ImageFileCache.Instance.GetImage(ImageBuckleName.small_images, this._URL); lock (_Locker) { _IsReady = true; } return; } */ Task.Run(() => { //判断图片路径是否为网络路径 if (IsUrl(this._URL)) { try { //读取文件 using (WebClient wc = new WebClient()) { Stream tream = wc.OpenRead(this._URL); this._Image = new Bitmap(tream); this._Image = new Bitmap(this._Image, new Size(60, 60));//缩放图片 /* //缓存图片 if (_UseLocalImage) ImageFileCache.Instance.AddImage(this._URL, this._Image, ImageBuckleName.small_images); */ } } catch (Exception ex) { this._Image = null; } lock (_Locker) { _IsReady = true; } RunNotify(); return; } }); } public void AddListener(DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs obj) { if (this._IsReady) { obj.Value = this._Image; } else { lock (_Locker) { _listens.Add(obj); } } } void refreshCell(DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs obj) {
// #002 异步加载,还未加载完成,就把窗体关掉了,造成obj对象为空
if (obj == null || obj.Column == null || obj.Column.View == null) return;
int handle = obj.Column.View.GetRowHandle(obj.ListSourceRowIndex);
// #001 if (handle >= 0) { if (obj.Column.View is GridView) { var view = obj.Column.View as GridView; view.RefreshRowCell(handle, obj.Column); } else { obj.Column.View.RefreshRow(handle); } } } void RunNotify() { lock (_Locker) { foreach (var obj in _listens) { refreshCell(obj); } _listens.Clear(); } } /// <summary> /// 识别urlStr是否是网络路径 /// </summary> /// <param name="url"></param> /// <returns></returns> public static bool IsUrl(string url) { if (Regex.IsMatch(url, @"((http|ftp|https)://)(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\&%_\./-~-]*)?")) { return true; } else { return false; } } }
GarsonZhang www.yesdotnet.com
#001 2021年5月23日 修复第一行的图片没显示bug
#002 2021年5月28日 修复窗体打开后图片还未加载完成就关闭,出现异常
设置GridView 图片列列Column的 UnboundType
属性为Object
添加表格的 CustomUnboundColumnData
事件
Dictionary<string, AsynDownImage> images = new Dictionary<string, AsynDownImage>(); private void gvSummary_CustomUnboundColumnData(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs e) { if (e.Column.Name == "col_ThumbSmall" && e.IsGetData) { string imgUrl = (string)((Ali1688_Products)e.Row).summURL.ToLower(); if (String.IsNullOrWhiteSpace(imgUrl)) { e.Value = null; return; } if (images.ContainsKey(imgUrl)) { images[imgUrl].AddListener(e); } else { AsynDownImage down = new AsynDownImage(imgUrl); down.AddListener(e); images[imgUrl] = down; } } }
GarsonZhang www.yesdotnet.com
效果预览:
别忘了修改 gridview.RowHeight 来设置行高
方案二,纯异步加载(不推荐,仅作为研究)
private void ShowDetailImgURL() { DataTable dt = gcDetail.DataSource as DataTable; string filePath = ConvertEx.ToString(_BLL.DataBindRow[tb_SaleOrder.__KeyName]); if (dt != null) { if(filePath != Globals.DEF_NO_TEXT) { CommonTools.GetImagePath(ConvertEx.ToString(_BLL.DataBindRow[tb_SaleOrder.__KeyName])); } string ImgPath = AppDomain.CurrentDomain.BaseDirectory + Globals.DEF_PIC_PATH + ConvertEx.ToString(_BLL.DataBindRow[tb_SaleOrder.__KeyName]) + @"\"; foreach (DataRow R in dt.Rows) { string URL = ConvertEx.ToString(R[tb_SaleOrders.ImgURL]); string ImgID = ConvertEx.ToString(R[tb_SaleOrders.ImgID]); if (R.RowState == DataRowState.Deleted) continue; if (!string.IsNullOrEmpty(URL)) { Task.Run(() => { WebRequest webRequest = WebRequest.Create(URL); using (HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse()) { using (Stream s = response.GetResponseStream()) { using (Image img = Image.FromStream(s)) { try { this.Invoke(new Action((delegate { if (!File.Exists(ImgPath + ImgID + ".jpg")) { img.Save(ImgPath + ImgID + ".jpg"); } R[tb_SaleOrders.OriginalPicture] = CImageLibrary.GetImageBytes(img, ImageFormat.Jpeg); }))); } catch (Exception ex) { throw ex; } finally { // } } } } }); } } } }
GarsonZhang www.infnitee.com
版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
post YES开发框架