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(); } } }