在DevExpress GridControl的一列中顯示圖片

衣舞晨風發表於2015-03-19

        作者:jiankunking 出處:http://blog.csdn.net/jiankunking

        最近做專案的時候用到了將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];
            }
        }




相關文章