最近做项目的时候用到了将GridControl中一列设置为PictureEdit类型,然后通过这一列来显示图片。经过尝试发现有以下两种方式可行。
方法一、知道图片的路径与名称
比如:在数据库中存储了图片的路径(包括:本地路径、服务器路径),那么在可以通过非绑定列的方式来实现。
1、创建了一个非绑定列并设置其相应的属性,属性设置如下:
FieldName设为 Photo(该字段名必须是唯一的)
UnboundType设为 UnboundColumnType.Object
ColumnEdit设为RepositoryItemPictureEdit类的实例(该操作PictureEdit 为该列的内置编辑器)
2.、添加GridView的CustomUnboundColumnData事件,用于为非绑定列填充数据。
既然已经设置完成了,那么具体的代码怎么编写呢?具体代码如下:
private void gridView1_CustomUnboundColumnData(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs e) { if (e.Column.FieldName == "Photo" && e.IsGetData) { //RefImage是存储图片路径的那一列 string filePath = (string)((DataRowView)e.Row)["RefImage"]; Image img = null; try { //判断图片路径是否为网络路径 if (UrlDiscern(filePath)) { //文件是否存在 if (RemoteFileExists(filePath)) { //读取文件 using (WebClient wc = new WebClient()) { img = new Bitmap(wc.OpenRead(filePath)); } } } // 判断本地文件是否存在 else if (LocalFileExists(filePath)) { //加载本地图片 img = Image.FromFile(filePath); } //pictureEdit列绑定图片 e.Value = img; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } } /// <summary> /// 判断远程文件是否存在 /// </summary> /// <param name="fileUrl"></param> /// <returns></returns> public bool RemoteFileExists(string fileUrl) { HttpWebRequest re = null; HttpWebResponse res = null; try { re = (HttpWebRequest)WebRequest.Create(fileUrl); res = (HttpWebResponse)re.GetResponse(); if (res.ContentLength != 0) { //MessageBox.Show("文件存在"); return true; } } catch (Exception) { //MessageBox.Show("无此文件"); return false; } finally { if (re != null) { re.Abort();//销毁关闭连接 } if (res != null) { res.Close();//销毁关闭响应 } } return false; } /// <summary> /// 判断本地文件是否存在 /// </summary> /// <param name="path"></param> /// <returns></returns> public bool LocalFileExists(string filePath) { if (File.Exists(filePath)) { return true; } else { return false; } } /// <summary> /// 识别urlStr是否是网络路径 /// </summary> /// <param name="urlStr"></param> /// <returns></returns> public bool UrlDiscern(string urlStr) { if (Regex.IsMatch(urlStr, @"((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; } }
如果图片在单元格中显示有问题的话,可以调整
方法二、知道图片的路径与名称
除了方法一之外,我们还可以使用流的方式的来加载图片,即根据图片路径将图片转化为流,然后直接绑定到RepositoryItemPictureEdit列上即可。此时不需要修改列的绑定类型,只需要该列的FieldName与数据源中的byte[]流的所在列的名称一致即可,
如果这么绑定无效的话,可以在gridcontrol的数据源(此处假设为Dataset)中新增一列
ds.Tables[0].Columns.Add("Photo", System.Type.GetType("System.Byte[]"));然后,根据路径加载图片到Photo列中,
<pre name="code" class="html"> byte[] bb = PubFunc.getImageByte(path, webClient); ds.Tables[0].Rows[i]["Photo"] = bb;其中,可能会用到的函数如下:
/// <summary> /// 返回图片的字节流byte[] /// </summary> /// <param name="imagePath"></param> /// <param name="webClient"></param> /// <returns></returns> public byte[] getImageByte(string imagePath) { byte[] imgByte = null; try { if (UrlDiscern(imagePath)) { using(WebClient webClient=new WebClient()) { Bitmap bt = new Bitmap(webClient.OpenRead(imagePath)); imgByte = PubFunc.ImgToByte(bt); } } else { using (FileStream files = new FileStream(imagePath, FileMode.Open)) { imgByte = new byte[files.Length]; files.Read(imgByte, 0, imgByte.Length); files.Close(); } } } catch (Exception ee) { MessageBox.Show(ee.ToString()); } return imgByte; }
/// <summary> /// 图片转换成字节流 /// </summary> /// <param name="img">要转换的Image对象</param> /// <returns>转换后返回的字节流</returns> public byte[] ImgToByte(Image img) { try { using (MemoryStream ms = new MemoryStream()) { byte[] imagedata = null; img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); imagedata = ms.GetBuffer(); return imagedata; } } catch (Exception ee) { MessageBox.Show(ee.ToString()); return null; } }
小注:
使用以上方法,快速滑动滑动条的时候,会出现卡死的现象,因为上述代码是每次实时读取图片资源的,应该加入一个图片路径、图片 字典,以减少图片的重复读取。
private void gridView1_CustomUnboundColumnData(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs e) { if (e.Column.FieldName == "Photo" && e.IsGetData) { string filePath = (string)((DataRowView)e.Row)["RefImage"]; if (!images.ContainsKey(filePath)) { Image img = null; try { if (PubFunc.UrlDiscern(filePath)) { if (FileUpDownload.RemoteFileExists(filePath)) { using (WebClient wc = new WebClient()) { //Bitmap bmtemp = new Bitmap(wc.OpenRead(filePath)); //img = new Bitmap(bmtemp, 75, 75); img = new Bitmap(wc.OpenRead(filePath)); } } } else if (PubFunc.LocalFileExists(filePath)) { img = Image.FromFile(filePath); } images.Add(filePath, img); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } e.Value = images[filePath]; } }