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开发框架网发布内容,转载请附上原文出处连接
YES开发框架
上一篇:解决.Net Core3.0 修改cshtml代码之后必须重新生成才可以看到效果
下一篇:NugetServer
评论列表

发表评论

评论内容
昵称:
关联文章

Devexpress 表格GridViewRepositoryItemPictureEdit异步远程URL图片
DevExpress表格GridControl添加操作单元格添加图片按钮并且实现点击链接URL跳转浏览器
[原创] Devexpress表格GridView展示星级等级星星图标
Devexpress GridControl GridView添加右键菜单
DevExpress表格GridView不触发CustomUnboundColumnData事件
Devexpress GridControl表格无法鼠标滚轮上下滚动
devexpress gridview显示分组group文本
Devexpress GridControl GridView双击事件优化
Devexpress GridView焦点离开表格的时候保持选中行的选中颜色
winform自定义控件(UserControl)慢的研究
C# 解析读取XML文件的正确姿势
MEF会缺少一些dll,
Devexpress表格GridControl主从表点击从表获得当前选中行
Devexpress表格主从表
Visual Studio 2019 远程调试工具(Remote Debugger)
.NET中大型项目开发必备(10)--图片的裁剪、缩放、与水印
C#多线程下载图片 URL转Image
服务安装失败:未能文件或程序集
Devexpress gridControl SummaryItem显示格式化设置DisplayFormat
WPF 组织机构摄像机树 全量 大数据量 分页摄像机节点

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码