GridControlEx.cs 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027
  1. using DevExpress.Utils;
  2. using DevExpress.Utils.Helpers;
  3. using DevExpress.Utils.Menu;
  4. using DevExpress.Utils.Paint;
  5. using DevExpress.Utils.Svg;
  6. using DevExpress.XtraBars;
  7. using DevExpress.XtraEditors;
  8. using DevExpress.XtraEditors.Controls;
  9. using DevExpress.XtraEditors.Repository;
  10. using DevExpress.XtraGrid;
  11. using DevExpress.XtraGrid.Columns;
  12. using DevExpress.XtraGrid.Views.Grid;
  13. using DxHelper;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Drawing;
  17. using System.IO;
  18. using System.Linq;
  19. using System.Text;
  20. using System.Threading.Tasks;
  21. using System.Windows.Forms;
  22. public static class GridControlEx
  23. {
  24. internal class GridTag
  25. {
  26. public GridTag() { }
  27. public PopupMenu PopupMenu { get; set; }
  28. public BarManager BarM { get; set; }
  29. public List<BarButtonItem> RowButtonsItems { get; set; } = new List<BarButtonItem>();
  30. public List<BarButtonItem> MultRowButtonsItems { get; set; } = new List<BarButtonItem>();
  31. }
  32. /// <summary>
  33. /// 初始化表格(默认禁用分组)
  34. /// </summary>
  35. /// <param name="grid"></param>
  36. /// <param name="dataSource">绑定的数据源</param>
  37. /// <param name="rowHeight">行高(默认24px)</param>
  38. /// <param name="showScrollH">是否显示水平滚动条(默认不显示)</param>
  39. /// <typeparam name="T">绑定的数据源模型类型</typeparam>
  40. /// <returns></returns>
  41. public static GridControl UseDefault<T>(this GridControl grid, List<T> dataSource, int rowHeight = 24, bool showScrollH = false)
  42. {
  43. grid.DataSource = dataSource;
  44. grid.HideColumn("ID","CreateTime","UpdateTime");
  45. grid.MainView.BorderStyle = BorderStyles.Flat;
  46. var view = grid.MainView as GridView;
  47. view.CustomColumnDisplayText += View_CustomColumnDisplayText;
  48. view.Appearance.HeaderPanel.TextOptions.HAlignment = HorzAlignment.Center;
  49. view.Appearance.Row.Options.UseTextOptions = true;
  50. view.Appearance.Row.TextOptions.HAlignment = HorzAlignment.Center;
  51. view.OptionsView.ColumnHeaderAutoHeight = DefaultBoolean.True;
  52. view.RowHeight = rowHeight;
  53. view.OptionsView.ShowGroupPanel = false;
  54. view.OptionsBehavior.Editable = false;
  55. view.OptionsView.ShowDetailButtons = false;
  56. view.OptionsView.ShowIndicator = false;
  57. view.OptionsMenu.EnableColumnMenu = true;
  58. view.OptionsCustomization.AllowFilter = true;
  59. view.OptionsCustomization.AllowGroup = false;
  60. view.OptionsCustomization.AllowSort = true;
  61. view.OptionsCustomization.AllowColumnMoving = true;
  62. view.OptionsCustomization.AllowMergedGrouping = DefaultBoolean.False;
  63. view.OptionsSelection.MultiSelect = false;
  64. view.OptionsCustomization.AllowRowSizing = false;
  65. view.OptionsCustomization.AllowQuickHideColumns = false;
  66. view.OptionsMenu.EnableGroupPanelMenu = false;
  67. view.OptionsMenu.EnableGroupRowMenu = false;
  68. view.OptionsMenu.EnableFooterMenu = false;
  69. view.OptionsLayout.StoreAllOptions = true;
  70. view.OptionsLayout.StoreAppearance = true;
  71. view.OptionsLayout.StoreDataSettings = true;
  72. view.OptionsLayout.StoreVisualOptions = true;
  73. view.OptionsLayout.StoreFormatRules = true;
  74. view.OptionsView.ColumnAutoWidth = !showScrollH;
  75. view.PopupMenuShowing += View_PopupMenuShowing;
  76. view.OptionsSelection.EnableAppearanceFocusedCell = false;
  77. string GetLayoutName()
  78. {
  79. Control ctrl;
  80. if (view.Tag is SearchLookUpEdit searchLookUpEdit)
  81. ctrl = searchLookUpEdit;
  82. else
  83. ctrl = grid;
  84. while (ctrl.Parent != null)
  85. {
  86. ctrl = ctrl.Parent;
  87. if (ctrl is UserControl) break;
  88. }
  89. var props = typeof(T).GetProperties();
  90. StringBuilder sb = new StringBuilder();
  91. foreach (var item in props)
  92. {
  93. sb.Append(item.Name);
  94. }
  95. var md5 = MD5Helper.StrToMD5(sb.ToString());
  96. if (view.Tag is SearchLookUpEdit searchLookUpEdit2)
  97. return $"{ctrl.Name}_{searchLookUpEdit2.Name}_{md5}";
  98. else
  99. return $"{ctrl.Name}_{grid.Name}_{md5}";
  100. }
  101. string name = GetLayoutName();
  102. void SaveLayoutAction()
  103. {
  104. Form frm = null;
  105. if (view.Tag is SearchLookUpEdit edit)
  106. frm = edit.FindForm();
  107. else
  108. frm = grid.FindForm();
  109. if (frm != null)
  110. {
  111. frm.VisibleChanged += (sender2, e2) =>
  112. {
  113. Directory.CreateDirectory("Layout");
  114. if (name == null) return;
  115. grid.MainView?.SaveLayoutToXml($"Layout\\{name}.xml", OptionsLayoutBase.FullLayout);
  116. };
  117. }
  118. }
  119. if (grid.IsLoaded)
  120. {
  121. SaveLayoutAction();
  122. }
  123. else
  124. {
  125. grid.Load += (sender, e) => SaveLayoutAction();
  126. }
  127. if (name != null && File.Exists($"Layout\\{name}.xml"))
  128. {
  129. view.RestoreLayoutFromXml($"Layout\\{name}.xml", OptionsLayoutBase.FullLayout);
  130. view.ClearColumnsFilter();
  131. view.ClearFindFilter();
  132. view.ClearInHeaderSearchText();
  133. view.ClearSorting();
  134. view.ClearSelection();
  135. }
  136. view.KeyUp += View_KeyUp;
  137. grid.Tag = new GridTag();
  138. return grid;
  139. }
  140. /// <summary>
  141. /// 为GirdControl启用右键新增数据的功能
  142. /// </summary>
  143. /// <param name="grid"></param>
  144. /// <param name="emptyText"></param>
  145. /// <returns></returns>
  146. public static GridControl UseEmptyText(this GridControl grid, string emptyText = "暂无数据")
  147. {
  148. if (string.IsNullOrWhiteSpace(emptyText)) return grid;
  149. var view = grid.MainView as GridView;
  150. view.CustomDrawEmptyForeground += (sender, e) =>
  151. {
  152. var s = e.Appearance.CalcTextSize(e.Cache, emptyText, e.Bounds.Width).ToSize();
  153. var x = (e.Bounds.Width - s.Width) / 2;
  154. var y = (e.Bounds.Height - s.Height) / 2;
  155. e.Appearance.ForeColor = Color.Gray;
  156. e.Appearance.DrawString(e.Cache, emptyText, new Rectangle(x, y, s.Width, s.Height));
  157. };
  158. return grid;
  159. }
  160. /// <summary>
  161. /// 为GirdControl启用右键新增数据的功能
  162. /// </summary>
  163. /// <typeparam name="T"></typeparam>
  164. /// <param name="grid"></param>
  165. /// <param name="menuCaption"></param>
  166. /// <param name="callback">一个回调函数,返回新增的数据</param>
  167. /// <returns></returns>
  168. public static GridControl UseAdd<T>(this GridControl grid, Func<T> callback, string menuCaption = "新增")
  169. {
  170. var view = grid.MainView as GridView;
  171. view.CustomDrawEmptyForeground += (sender, e) =>
  172. {
  173. string emptyText = "右键添加";
  174. var s = e.Appearance.CalcTextSize(e.Cache, emptyText, e.Bounds.Width).ToSize();
  175. var x = (e.Bounds.Width - s.Width) / 2;
  176. var y = (e.Bounds.Height - s.Height) / 2;
  177. e.Appearance.ForeColor = Color.Gray;
  178. e.Appearance.DrawString(e.Cache, emptyText, new Rectangle(x, y, s.Width, s.Height));
  179. };
  180. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateAdd(), data =>
  181. {
  182. if (callback != null)
  183. {
  184. var addRow = callback();
  185. if (addRow == null) return;
  186. var ds = grid.DataSource as List<T>;
  187. ds.Add(addRow);
  188. view.RefreshData();
  189. }
  190. }, true);
  191. return grid;
  192. }
  193. /// <summary>
  194. /// 为GirdControl启用右键新增数据的功能
  195. /// </summary>
  196. /// <typeparam name="T"></typeparam>
  197. /// <param name="grid"></param>
  198. /// <param name="menuCaption"></param>
  199. /// <param name="callback">一个回调函数,返回新增的数据</param>
  200. /// <returns></returns>
  201. public static GridControl UseAddAsync<T>(this GridControl grid, Func<Task<T>> callback, string menuCaption = "新增")
  202. {
  203. grid.AddContentMenuAsync<T>(menuCaption, DxHelper.SvgHelper.CreateAdd(), async data =>
  204. {
  205. if (callback != null)
  206. {
  207. var addRow = await callback();
  208. if (addRow == null) return;
  209. var view = grid.MainView as GridView;
  210. var ds = grid.DataSource as List<T>;
  211. ds.Add(addRow);
  212. view.RefreshData();
  213. }
  214. }, true);
  215. return grid;
  216. }
  217. /// <summary>
  218. /// 为GridControl启用右编辑选中的单行功能
  219. /// </summary>
  220. /// <typeparam name="T"></typeparam>
  221. /// <param name="grid"></param>
  222. /// <param name="menuCaption"></param>
  223. /// <param name="callback"></param>
  224. /// <returns></returns>
  225. public static GridControl UseEdit<T>(this GridControl grid, Func<T, T> callback, string menuCaption = "编辑")
  226. {
  227. grid.AddRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateEdit(), data =>
  228. {
  229. if (callback != null)
  230. {
  231. var newRow = callback(data);
  232. if (newRow == null) return;
  233. var view = grid.MainView as GridView;
  234. var ds = grid.DataSource as List<T>;
  235. var idx = ds.IndexOf(data);
  236. ds.Remove(data);
  237. ds.Insert(idx, newRow);
  238. view.RefreshData();
  239. }
  240. }, null);
  241. return grid;
  242. }
  243. /// <summary>
  244. /// 为GridControl启用右编辑选中的单行功能
  245. /// </summary>
  246. /// <typeparam name="T"></typeparam>
  247. /// <param name="grid"></param>
  248. /// <param name="menuCaption"></param>
  249. /// <param name="callback"></param>
  250. /// <returns></returns>
  251. public static GridControl UseEditAsync<T>(this GridControl grid, Func<T, Task<T>> callback, string menuCaption = "编辑")
  252. {
  253. grid.AddRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateEdit(), async data =>
  254. {
  255. if (callback != null)
  256. {
  257. var newRow = await callback(data);
  258. if (newRow == null) return;
  259. var view = grid.MainView as GridView;
  260. var ds = grid.DataSource as List<T>;
  261. var idx = ds.IndexOf(data);
  262. ds.Remove(data);
  263. ds.Insert(idx, newRow);
  264. view.RefreshData();
  265. }
  266. }, null);
  267. return grid;
  268. }
  269. /// <summary>
  270. /// 为GridControl启用右删除选中的一行或多行功能(自动启用UseMultiSelect)
  271. /// </summary>
  272. /// <typeparam name="T"></typeparam>
  273. /// <param name="grid"></param>
  274. /// <param name="menuCaption"></param>
  275. /// <param name="action"></param>
  276. /// <returns></returns>
  277. public static GridControl UseDelete<T>(this GridControl grid, Func<List<T>, bool> action = null, string menuCaption = "删除")
  278. {
  279. grid.AddMultRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClose(), data =>
  280. {
  281. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认删除选中的记录?共[{data.Count}]条")) return;
  282. if (action != null)
  283. {
  284. bool succeed = action(data);
  285. if (!succeed) return;
  286. }
  287. var view = grid.MainView as GridView;
  288. view.DeleteSelectedRows();
  289. view.RefreshData();
  290. });
  291. return grid;
  292. }
  293. /// <summary>
  294. /// 为GridControl启用右删除选中的一行或多行功能(自动启用UseMultiSelect)
  295. /// </summary>
  296. /// <typeparam name="T"></typeparam>
  297. /// <param name="grid"></param>
  298. /// <param name="menuCaption"></param>
  299. /// <param name="action"></param>
  300. /// <returns></returns>
  301. public static GridControl UseDeleteAsync<T>(this GridControl grid, Func<List<T>, Task<bool>> action = null, string menuCaption = "删除")
  302. {
  303. grid.AddMultRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClose(), async data =>
  304. {
  305. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认删除选中的记录?共[{data.Count()}]条")) return;
  306. if (action != null)
  307. {
  308. bool succeed = await action(data);
  309. if (!succeed) return;
  310. }
  311. var view = grid.MainView as GridView;
  312. view.DeleteSelectedRows();
  313. view.RefreshData();
  314. });
  315. return grid;
  316. }
  317. /// <summary>
  318. /// 为GirdControl启用右键清除所有数据的功能
  319. /// </summary>
  320. /// <typeparam name="T"></typeparam>
  321. /// <param name="grid"></param>
  322. /// <param name="menuCaption"></param>
  323. /// <param name="action"></param>
  324. /// <returns></returns>
  325. public static GridControl UseClear<T>(this GridControl grid, Func<List<T>, bool> action = null, string menuCaption = "清除")
  326. {
  327. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClear(), data =>
  328. {
  329. if (data == null || data.Count == 0) return;
  330. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认清空所有记录?共[{data.Count}]条")) return;
  331. if (action != null)
  332. {
  333. bool succeed = action(data);
  334. if (!succeed) return;
  335. }
  336. var view = grid.MainView as GridView;
  337. data.Clear();
  338. view.RefreshData();
  339. }, false);
  340. return grid;
  341. }
  342. public static GridControl SetLogImageColumn(this GridControl grid, string columnFieldName,Type enumType)
  343. {
  344. var view = grid.MainView as GridView;
  345. RepositoryItemImageComboBox edit = new RepositoryItemImageComboBox();
  346. edit.AddEnum(enumType);
  347. SvgImageCollection svgImages = new SvgImageCollection();
  348. svgImages.ImageSize = new System.Drawing.Size(20, 20);
  349. svgImages.Add(SvgHelper.CreateInfo());
  350. svgImages.Add(SvgHelper.CreateWarning());
  351. svgImages.Add(SvgHelper.CreateError());
  352. edit.SmallImages = svgImages;
  353. edit.GlyphAlignment = DevExpress.Utils.HorzAlignment.Center;
  354. view.Columns[columnFieldName].ColumnEdit = edit;
  355. return grid;
  356. }
  357. /// <summary>
  358. /// 为GirdControl启用右键清除所有数据的功能
  359. /// </summary>
  360. /// <typeparam name="T"></typeparam>
  361. /// <param name="grid"></param>
  362. /// <param name="menuCaption"></param>
  363. /// <param name="action"></param>
  364. /// <returns></returns>
  365. public static GridControl UseClearAsync<T>(this GridControl grid, Func<List<T>, Task<bool>> action = null, string menuCaption = "清除")
  366. {
  367. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClear(), async data =>
  368. {
  369. if (data == null || data.Count == 0) return;
  370. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认清空所有记录?共[{data.Count}]条")) return;
  371. if (action != null)
  372. {
  373. bool succeed = await action(data);
  374. if (!succeed) return;
  375. }
  376. var view = grid.MainView as GridView;
  377. data.Clear();
  378. view.RefreshData();
  379. }, false);
  380. return grid;
  381. }
  382. public static GridControl UseExportCsv(this GridControl grid)
  383. {
  384. GridTag tag = grid.Tag as GridTag;
  385. if (tag.BarM == null)
  386. {
  387. tag.BarM = new BarManager();
  388. tag.BarM.Form = grid;
  389. }
  390. if (tag.PopupMenu == null)
  391. {
  392. tag.PopupMenu = new PopupMenu();
  393. }
  394. PopupMenu popupMenu = tag.PopupMenu;
  395. BarButtonItem item = new BarButtonItem();
  396. item.ItemClick += (sender, e) =>
  397. {
  398. SaveFileDialog dialog = new SaveFileDialog();
  399. dialog.Filter = "csv|*.csv";
  400. if (dialog.ShowDialog() == DialogResult.OK)
  401. {
  402. var view = grid.MainView as GridView;
  403. view.ExportToCsv(dialog.FileName);
  404. }
  405. };
  406. item.ImageOptions.SvgImage = DxHelper.SvgHelper.CreateExportCsv();
  407. item.Caption = "导出(CSV)";
  408. tag.BarM.Items.Add(item);
  409. popupMenu.AddItem(item);
  410. popupMenu.Manager = tag.BarM;
  411. tag.PopupMenu = popupMenu;
  412. return grid;
  413. }
  414. public static GridControl AddMenu(this GridControl grid, string menuText, SvgImage meunImage, Action onClick)
  415. {
  416. GridTag tag = grid.Tag as GridTag;
  417. if (tag.BarM == null)
  418. {
  419. tag.BarM = new BarManager();
  420. tag.BarM.Form = grid;
  421. }
  422. if (tag.PopupMenu == null)
  423. {
  424. tag.PopupMenu = new PopupMenu();
  425. }
  426. PopupMenu popupMenu = tag.PopupMenu;
  427. BarButtonItem item = new BarButtonItem();
  428. item.ItemClick += (sender, e) =>
  429. {
  430. item.Enabled = false;
  431. onClick?.Invoke();
  432. item.Enabled = true;
  433. };
  434. item.ImageOptions.SvgImage = meunImage;
  435. item.Caption = menuText;
  436. tag.BarM.Items.Add(item);
  437. popupMenu.AddItem(item);
  438. popupMenu.Manager = tag.BarM;
  439. tag.PopupMenu = popupMenu;
  440. return grid;
  441. }
  442. public static GridControl UseExportXlsx(this GridControl grid)
  443. {
  444. GridTag tag = grid.Tag as GridTag;
  445. if (tag.BarM == null)
  446. {
  447. tag.BarM = new BarManager();
  448. tag.BarM.Form = grid;
  449. }
  450. if (tag.PopupMenu == null)
  451. {
  452. tag.PopupMenu = new PopupMenu();
  453. }
  454. PopupMenu popupMenu = tag.PopupMenu;
  455. BarButtonItem item = new BarButtonItem();
  456. item.ItemClick += (sender, e) =>
  457. {
  458. SaveFileDialog dialog = new SaveFileDialog();
  459. dialog.Filter = "Excel文件|*.xlsx";
  460. if (dialog.ShowDialog() == DialogResult.OK)
  461. {
  462. var view = grid.MainView as GridView;
  463. view.ExportToXlsx(dialog.FileName);
  464. }
  465. };
  466. item.ImageOptions.SvgImage = DxHelper.SvgHelper.CreateExportXlsx();
  467. item.Caption = "导出(Excel)";
  468. tag.BarM.Items.Add(item);
  469. popupMenu.AddItem(item);
  470. popupMenu.Manager = tag.BarM;
  471. tag.PopupMenu = popupMenu;
  472. return grid;
  473. }
  474. private static void View_KeyUp(object sender, KeyEventArgs e)
  475. {
  476. if (e.Control && e.Shift & e.KeyCode == Keys.C)
  477. {
  478. var view = sender as GridView;
  479. if (view.FocusedColumn == null) return;
  480. var val = view.GetFocusedRowCellDisplayText(view.FocusedColumn);
  481. if (string.IsNullOrWhiteSpace(val)) return;
  482. Clipboard.SetText(val);
  483. }
  484. }
  485. private static void View_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e)
  486. {
  487. if (e.Column.ColumnType == typeof(DateTime) || e.Column.ColumnType == typeof(DateTime?))
  488. {
  489. if (e.Value == null) return;
  490. if (e.Column.FieldName == "SigTime")
  491. e.DisplayText = Convert.ToDateTime(e.Value).ToString("yyyy-MM-dd HH:mm:ss.fff");
  492. else
  493. e.DisplayText = Convert.ToDateTime(e.Value).ToString("yyyy-MM-dd HH:mm:ss");
  494. }
  495. }
  496. public static GridControl ShowColumn(this GridControl grid, params string[] colField)
  497. {
  498. var view = grid.MainView as GridView;
  499. if (view.Columns.Count == 0) return grid;
  500. if (colField == null || colField.Length == 0) return grid;
  501. foreach (GridColumn item in view.Columns)
  502. {
  503. if (colField.Contains(item.FieldName))
  504. item.Visible = true;
  505. }
  506. return grid;
  507. }
  508. public static GridControl UseMultiSelect(this GridControl grid)
  509. {
  510. var view = grid.MainView as GridView;
  511. view.OptionsSelection.MultiSelect = true;
  512. view.OptionsSelection.MultiSelectMode = GridMultiSelectMode.RowSelect;
  513. return grid;
  514. }
  515. public static GridControl UseGroup(this GridControl grid)
  516. {
  517. var view = grid.MainView as GridView;
  518. view.OptionsView.GroupFooterShowMode = GroupFooterShowMode.Hidden;
  519. view.OptionsView.ShowGroupPanel = true;
  520. view.OptionsCustomization.AllowGroup = true;
  521. view.OptionsCustomization.AllowSort = true;
  522. return grid;
  523. }
  524. public static GridControl UseFooter(this GridControl grid, Action<object, DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgs> act)
  525. {
  526. var view = grid.MainView as GridView;
  527. view.OptionsView.ShowFooter = true;
  528. view.CustomDrawFooter += (s, e) => act(s, e);
  529. return grid;
  530. }
  531. public static GridControl UseEdit(this GridControl grid)
  532. {
  533. var view = grid.MainView as GridView;
  534. view.OptionsBehavior.Editable = true;
  535. view.OptionsSelection.EnableAppearanceFocusedCell = true;
  536. foreach (GridColumn item in view.Columns)
  537. {
  538. item.OptionsColumn.AllowEdit = false;
  539. }
  540. return grid;
  541. }
  542. public static GridControl UseRowNumber(this GridControl grid)
  543. {
  544. var view = grid.MainView as GridView;
  545. view.OptionsView.ShowIndicator = true;
  546. view.CustomDrawRowIndicator += (s, e) =>
  547. {
  548. if (!e.Info.IsRowIndicator) return;
  549. if (e.RowHandle < 0) return;
  550. e.Handled = true;
  551. string txt = (e.RowHandle + 1).ToString();
  552. var txtSize = e.Graphics.MeasureString(txt, e.Appearance.Font);
  553. if (view.IndicatorWidth < txtSize.Width + 20)
  554. {
  555. view.IndicatorWidth++;
  556. }
  557. var loc = new PointF(e.Bounds.X + e.Bounds.Width / 2f - txtSize.Width / 2f + 2,
  558. e.Bounds.Y + e.Bounds.Height / 2f - txtSize.Height / 2f);
  559. e.Cache.FillRectangle(new SolidBrush(e.Appearance.BackColor), e.Bounds);
  560. e.Cache.DrawString(txt, e.Appearance.Font, new SolidBrush(e.Appearance.ForeColor), loc);
  561. };
  562. view.RowCountChanged += (sender, e) =>
  563. {
  564. if (view.RowCount == 0)
  565. view.IndicatorWidth = -1;
  566. else
  567. view.IndicatorWidth = view.RowCount.ToString().Length * 6 + 20;
  568. };
  569. return grid;
  570. }
  571. public static GridControl UseNullValueText(this GridControl grid, string nullText = "--")
  572. {
  573. var view = grid.MainView as GridView;
  574. view.CustomColumnDisplayText += (sender, e) =>
  575. {
  576. if (e.Value == null) e.DisplayText = nullText;
  577. };
  578. return grid;
  579. }
  580. public static GridControl SetDisplayText(this GridControl grid, string columnFieldName, Func<object, string> action)
  581. {
  582. var view = grid.MainView as GridView;
  583. view.CustomColumnDisplayText += (sender, e) =>
  584. {
  585. if (e.Column.FieldName != columnFieldName) return;
  586. if (e.Value == null || action == null) return;
  587. e.DisplayText = action(e.Value);
  588. };
  589. return grid;
  590. }
  591. public static GridControl HideColumn(this GridControl grid, params string[] colField)
  592. {
  593. var view = grid.MainView as GridView;
  594. if (colField == null || colField.Length == 0) return grid;
  595. foreach (GridColumn item in view.Columns)
  596. {
  597. if (colField.Contains(item.FieldName))
  598. item.Visible = false;
  599. }
  600. return grid;
  601. }
  602. public static GridControl HideColumn(this GridControl grid, Func<GridColumn, bool> condition)
  603. {
  604. var view = grid.MainView as GridView;
  605. foreach (GridColumn item in view.Columns)
  606. {
  607. if (item.ColumnEdit == null && condition(item))
  608. item.Visible = false;
  609. }
  610. return grid;
  611. }
  612. /// <summary>
  613. /// GridControl添加单行元素选择后的右键菜单
  614. /// </summary>
  615. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  616. /// <param name="grid">GridControl控件</param>
  617. /// <param name="menuText">菜单标题</param>
  618. /// <param name="meunImage">菜单图标</param>
  619. /// <param name="action">菜单要执行的事件函数,参数为选中的单行元素</param>
  620. /// <param name="showCondition">菜单显示的条件</param>
  621. /// <returns></returns>
  622. public static GridControl AddRowMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  623. Action<T> action, Func<T, bool> showCondition = null)
  624. {
  625. GridTag tag = grid.Tag as GridTag;
  626. var view = grid.MainView as GridView;
  627. if (tag.BarM == null)
  628. {
  629. tag.BarM = new BarManager();
  630. tag.BarM.Form = grid;
  631. }
  632. if (tag.PopupMenu == null)
  633. {
  634. tag.PopupMenu = new PopupMenu();
  635. }
  636. var popupMenu = tag.PopupMenu;
  637. BarButtonItem item = new BarButtonItem();
  638. tag.RowButtonsItems.Add(item);
  639. Func<bool> showConditionAll = () =>
  640. {
  641. if (!view.GetSelectedRows().Any()) return false;
  642. if (showCondition == null)
  643. return true;
  644. else
  645. return showCondition((T)view.GetFocusedRow());
  646. };
  647. item.Tag = showConditionAll;
  648. var handle = new ItemClickEventHandler((sender, e) =>
  649. {
  650. if (action != null)
  651. {
  652. if (view.GetFocusedRow() == null) return;
  653. item.Enabled = false;
  654. action.Invoke((T)view.GetFocusedRow());
  655. item.Enabled = true;
  656. }
  657. });
  658. item.Events().AddHandler(menuText, handle);
  659. item.ItemClick += handle;
  660. item.ImageOptions.SvgImage = meunImage;
  661. item.Caption = menuText;
  662. tag.BarM.Items.Add(item);
  663. popupMenu.AddItem(item);
  664. popupMenu.Manager = tag.BarM;
  665. tag.PopupMenu = popupMenu;
  666. return grid;
  667. }
  668. /// <summary>
  669. /// GridControl添加单行元素选择后的右键菜单
  670. /// </summary>
  671. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  672. /// <param name="grid">GridControl控件</param>
  673. /// <param name="menuText">菜单标题</param>
  674. /// <param name="meunImage">菜单图标</param>
  675. /// <param name="action">菜单要执行的异步事件函数,参数为选中的单行元素</param>
  676. /// <param name="showCondition">菜单显示的条件</param>
  677. /// <returns></returns>
  678. public static GridControl AddRowMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  679. Func<T, Task> action, Func<T, bool> showCondition = null)
  680. {
  681. GridTag tag = grid.Tag as GridTag;
  682. var view = grid.MainView as GridView;
  683. if (tag.BarM == null)
  684. {
  685. tag.BarM = new BarManager();
  686. tag.BarM.Form = grid;
  687. }
  688. if (tag.PopupMenu == null)
  689. {
  690. tag.PopupMenu = new PopupMenu();
  691. }
  692. var popupMenu = tag.PopupMenu;
  693. BarButtonItem item = new BarButtonItem();
  694. tag.RowButtonsItems.Add(item);
  695. Func<bool> showConditionAll = () =>
  696. {
  697. if (!view.GetSelectedRows().Any()) return false;
  698. if (showCondition == null)
  699. return true;
  700. else
  701. return showCondition((T)view.GetFocusedRow());
  702. };
  703. item.Tag = showConditionAll;
  704. var handle = new ItemClickEventHandler(async (sender, e) =>
  705. {
  706. if (action != null)
  707. {
  708. if (view.GetFocusedRow() == null) return;
  709. item.Enabled = false;
  710. await action.Invoke((T)view.GetFocusedRow());
  711. item.Enabled = true;
  712. }
  713. });
  714. item.Events().AddHandler(menuText, handle);
  715. item.ItemClick += handle;
  716. item.ImageOptions.SvgImage = meunImage;
  717. item.Caption = menuText;
  718. tag.BarM.Items.Add(item);
  719. popupMenu.AddItem(item);
  720. popupMenu.Manager = tag.BarM;
  721. tag.PopupMenu = popupMenu;
  722. return grid;
  723. }
  724. /// <summary>
  725. /// GridControl添加多行选择元素的右键菜单(自动启用UseMultiSelect)
  726. /// </summary>
  727. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  728. /// <param name="grid">GridControl控件</param>
  729. /// <param name="menuText">菜单标题</param>
  730. /// <param name="meunImage">菜单图标</param>
  731. /// <param name="action">菜单要执行的事件,参数为选中的一行或多行元素</param>
  732. /// <returns></returns>
  733. public static GridControl AddMultRowMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  734. Action<List<T>> action)
  735. {
  736. grid.UseMultiSelect();
  737. GridTag tag = grid.Tag as GridTag;
  738. var view = grid.MainView as GridView;
  739. if (tag.BarM == null)
  740. {
  741. tag.BarM = new BarManager();
  742. tag.BarM.Form = grid;
  743. }
  744. if (tag.PopupMenu == null)
  745. {
  746. tag.PopupMenu = new PopupMenu();
  747. }
  748. var popupMenu = tag.PopupMenu;
  749. BarButtonItem item = new BarButtonItem();
  750. var handle = new ItemClickEventHandler((sender, e) =>
  751. {
  752. if (action != null)
  753. {
  754. var rows = view.GetSelectedRows();
  755. List<T> list = new List<T>();
  756. foreach (var row in rows)
  757. {
  758. if (row < 0) continue;
  759. list.Add((T)view.GetRow(row));
  760. }
  761. if (list.Any())
  762. action.Invoke(list);
  763. }
  764. });
  765. item.Events().AddHandler(menuText, handle);
  766. item.ItemClick += handle;
  767. item.ImageOptions.SvgImage = meunImage;
  768. item.Caption = menuText;
  769. Func<bool> showCondition = () => view.GetSelectedRows().Any();
  770. item.Tag = showCondition;
  771. tag.BarM.Items.Add(item);
  772. popupMenu.AddItem(item);
  773. popupMenu.Manager = tag.BarM;
  774. tag.PopupMenu = popupMenu;
  775. return grid;
  776. }
  777. /// <summary>
  778. /// GridControl添加多行选择元素的右键菜单(自动启用UseMultiSelect)
  779. /// </summary>
  780. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  781. /// <param name="grid">GridControl控件</param>
  782. /// <param name="menuText">菜单标题</param>
  783. /// <param name="meunImage">菜单图标</param>
  784. /// <param name="action">菜单要执行的异步事件函数,参数为选中的一行或多行元素</param>
  785. /// <returns></returns>
  786. public static GridControl AddMultRowMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  787. Func<List<T>, Task> action)
  788. {
  789. grid.UseMultiSelect();
  790. GridTag tag = grid.Tag as GridTag;
  791. var view = grid.MainView as GridView;
  792. if (tag.BarM == null)
  793. {
  794. tag.BarM = new BarManager();
  795. tag.BarM.Form = grid;
  796. }
  797. if (tag.PopupMenu == null)
  798. {
  799. tag.PopupMenu = new PopupMenu();
  800. }
  801. var popupMenu = tag.PopupMenu;
  802. BarButtonItem item = new BarButtonItem();
  803. var handle = new ItemClickEventHandler(async (sender, e) =>
  804. {
  805. if (action != null)
  806. {
  807. var rows = view.GetSelectedRows();
  808. List<T> list = new List<T>();
  809. foreach (var row in rows)
  810. {
  811. if (row < 0) continue;
  812. list.Add((T)view.GetRow(row));
  813. }
  814. if (list.Any())
  815. await action.Invoke(list);
  816. }
  817. });
  818. item.Events().AddHandler(menuText, handle);
  819. item.ItemClick += handle;
  820. item.ImageOptions.SvgImage = meunImage;
  821. item.Caption = menuText;
  822. Func<bool> showCondition = () => view.GetSelectedRows().Any();
  823. item.Tag = showCondition;
  824. tag.BarM.Items.Add(item);
  825. popupMenu.AddItem(item);
  826. popupMenu.Manager = tag.BarM;
  827. tag.PopupMenu = popupMenu;
  828. return grid;
  829. }
  830. /// <summary>
  831. /// GridControl添加内容区的右键菜单
  832. /// </summary>
  833. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  834. /// <param name="grid">GridControl控件</param>
  835. /// <param name="menuText">菜单标题</param>
  836. /// <param name="meunImage">菜单图标</param>
  837. /// <param name="action">菜单要执行的事件,参数为绑定的数据源</param>
  838. /// <param name="showWithNoneDataRow">内容区没有元素时是否显示此菜单,默认显示</param>
  839. /// <returns></returns>
  840. public static GridControl AddContentMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  841. Action<List<T>> action, bool showWithNoneDataRow = true)
  842. {
  843. GridTag tag = grid.Tag as GridTag;
  844. var view = grid.MainView as GridView;
  845. if (tag.BarM == null)
  846. {
  847. tag.BarM = new BarManager();
  848. tag.BarM.Form = grid;
  849. }
  850. if (tag.PopupMenu == null)
  851. {
  852. tag.PopupMenu = new PopupMenu();
  853. }
  854. var popupMenu = tag.PopupMenu;
  855. BarButtonItem item = new BarButtonItem();
  856. var handle = new ItemClickEventHandler((sender, e) =>
  857. {
  858. if (action != null)
  859. {
  860. var ds = grid.DataSource as List<T>;
  861. if (!showWithNoneDataRow && (ds == null || ds.Count == 0)) return;
  862. item.Enabled = false;
  863. action.Invoke(ds);
  864. item.Enabled = true;
  865. }
  866. });
  867. item.Events().AddHandler(menuText, handle);
  868. item.ItemClick += handle;
  869. item.ImageOptions.SvgImage = meunImage;
  870. item.Caption = menuText;
  871. tag.BarM.Items.Add(item);
  872. popupMenu.AddItem(item);
  873. popupMenu.Manager = tag.BarM;
  874. tag.PopupMenu = popupMenu;
  875. return grid;
  876. }
  877. /// <summary>
  878. /// GridControl添加内容区的右键菜单
  879. /// </summary>
  880. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  881. /// <param name="grid">GridControl控件</param>
  882. /// <param name="menuText">菜单标题</param>
  883. /// <param name="meunImage">菜单图标</param>
  884. /// <param name="action">菜单要执行的事件,参数为绑定的数据源</param>
  885. /// <param name="showWithNoneDataRow">内容区没有元素时是否显示此菜单,默认显示</param>
  886. /// <returns></returns>
  887. public static GridControl AddContentMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  888. Func<List<T>, Task> action, bool showWithNoneDataRow = true)
  889. {
  890. GridTag tag = grid.Tag as GridTag;
  891. var view = grid.MainView as GridView;
  892. if (tag.BarM == null)
  893. {
  894. tag.BarM = new BarManager();
  895. tag.BarM.Form = grid;
  896. }
  897. if (tag.PopupMenu == null)
  898. {
  899. tag.PopupMenu = new PopupMenu();
  900. }
  901. var popupMenu = tag.PopupMenu;
  902. BarButtonItem item = new BarButtonItem();
  903. var handle = new ItemClickEventHandler(async (sender, e) =>
  904. {
  905. if (action != null)
  906. {
  907. var ds = grid.DataSource as List<T>;
  908. if (!showWithNoneDataRow && (ds == null || ds.Count == 0)) return;
  909. item.Enabled = false;
  910. await action.Invoke(ds);
  911. item.Enabled = true;
  912. }
  913. });
  914. item.Events().AddHandler(menuText, handle);
  915. item.ItemClick += handle;
  916. item.ImageOptions.SvgImage = meunImage;
  917. item.Caption = menuText;
  918. tag.BarM.Items.Add(item);
  919. popupMenu.AddItem(item);
  920. popupMenu.Manager = tag.BarM;
  921. tag.PopupMenu = popupMenu;
  922. return grid;
  923. }
  924. private static void View_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e)
  925. {
  926. if (e.Menu != null)
  927. {
  928. foreach (DXMenuItem item in e.Menu.Items)
  929. {
  930. if (!item.Enabled)
  931. {
  932. item.Visible = false;
  933. continue;
  934. }
  935. }
  936. }
  937. //if (e.HitInfo.HitTest == DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitTest.EmptyRow)
  938. //{
  939. // return;
  940. //}
  941. var view = sender as GridView;
  942. var grid = view.GridControl;
  943. var p = grid.PointToScreen(e.Point);
  944. var tag = grid.Tag as GridTag;
  945. if (tag?.PopupMenu != null)
  946. {
  947. foreach (BarButtonItemLink item in tag?.PopupMenu?.ItemLinks)
  948. {
  949. var buttonItem = item.Item;
  950. if (buttonItem.Tag != null && buttonItem.Tag is Func<bool> showCondition)
  951. {
  952. if (showCondition())
  953. buttonItem.Visibility = BarItemVisibility.Always;
  954. else
  955. buttonItem.Visibility = BarItemVisibility.Never;
  956. }
  957. }
  958. tag?.PopupMenu?.ShowPopup(p);
  959. }
  960. }
  961. public static GridControl DrawGridColumnHeaderCheckBox(this GridControl grid)
  962. {
  963. //View的 Editable要为true
  964. var view = grid.MainView as GridView;
  965. view.OptionsBehavior.Editable = true;
  966. view.OptionsSelection.MultiSelect = true;
  967. view.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CheckBoxRowSelect;
  968. foreach (GridColumn item in view.Columns)
  969. {
  970. item.OptionsColumn.AllowEdit = false;
  971. }
  972. return grid;
  973. }
  974. }