GridControlEx.cs 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408
  1. using DevExpress.Utils;
  2. using DevExpress.Utils.Helpers;
  3. using DevExpress.Utils.Menu;
  4. using DevExpress.Utils.Svg;
  5. using DevExpress.XtraBars;
  6. using DevExpress.XtraEditors;
  7. using DevExpress.XtraEditors.Controls;
  8. using DevExpress.XtraEditors.Repository;
  9. using DevExpress.XtraGrid;
  10. using DevExpress.XtraGrid.Columns;
  11. using DevExpress.XtraGrid.Views.Grid;
  12. using DevExpress.XtraRichEdit.Model;
  13. using DxHelper;
  14. using ExtensionsDev;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.ComponentModel;
  18. using System.Drawing;
  19. using System.IO;
  20. using System.Linq;
  21. using System.Text;
  22. using System.Threading.Tasks;
  23. using System.Windows.Forms;
  24. public static class GridControlEx
  25. {
  26. internal class GridTag
  27. {
  28. public GridTag() { }
  29. public PopupMenu PopupMenu { get; set; }
  30. public BarManager BarM { get; set; }
  31. public List<BarButtonItem> RowButtonsItems { get; set; } = new List<BarButtonItem>();
  32. public List<BarButtonItem> MultRowButtonsItems { get; set; } = new List<BarButtonItem>();
  33. }
  34. /// <summary>
  35. /// 初始化表格(默认禁用分组)
  36. /// </summary>
  37. /// <param name="grid"></param>
  38. /// <param name="dataSource">绑定的数据源</param>
  39. /// <param name="rowHeight">行高(默认24px)</param>
  40. /// <param name="showScrollH">是否显示水平滚动条(默认不显示)</param>
  41. /// <typeparam name="T">绑定的数据源模型类型</typeparam>
  42. /// <returns></returns>
  43. public static GridControl UseDefault<T>(this GridControl grid, List<T> dataSource, int rowHeight = 24, bool showScrollH = false, bool formatNullValue = true)
  44. {
  45. grid.DataSource = dataSource;
  46. grid.Load += (sender, e) =>
  47. {
  48. grid.HideColumn("UpdateTime");
  49. grid.HideColumn(p => p.FieldName.ToUpper().EndsWith("ID"));
  50. grid.HideColumn(p => p.ColumnType == typeof(List<>));
  51. grid.HideColumn(p => p.ColumnType == typeof(ICollection<>));
  52. grid.HideColumn(p => p.ColumnType.BaseType != null && p.ColumnType.BaseType.Name.Contains("BaseEntity"));
  53. };
  54. grid.MainView.BorderStyle = BorderStyles.Flat;
  55. var view = grid.MainView as GridView;
  56. SetViewDefaultProps(grid, view, rowHeight, showScrollH);
  57. var childView = grid.GetChildView();
  58. if (childView != null)
  59. {
  60. view.OptionsView.ShowDetailButtons = true;
  61. SetViewDefaultProps(grid, childView, rowHeight, showScrollH);
  62. childView.OptionsMenu.EnableColumnMenu = false;
  63. childView.OptionsCustomization.AllowSort = false;
  64. childView.OptionsCustomization.AllowFilter = false;
  65. childView.OptionsCustomization.AllowGroup = false;
  66. }
  67. grid.Tag = new GridTag();
  68. if (formatNullValue)
  69. grid.UseNullValueText();
  70. return grid;
  71. }
  72. /// <summary>
  73. /// 初始化表格(默认禁用分组)
  74. /// </summary>
  75. /// <param name="grid"></param>
  76. /// <param name="dataSource">绑定的数据源</param>
  77. /// <param name="rowHeight">行高(默认24px)</param>
  78. /// <param name="showScrollH">是否显示水平滚动条(默认不显示)</param>
  79. /// <typeparam name="T">绑定的数据源模型类型</typeparam>
  80. /// <returns></returns>
  81. public static GridControl UseDefaultEx<T>(this GridControl grid, BindingList<T> dataSource, int rowHeight = 24, bool showScrollH = false, bool formatNullValue = true)
  82. {
  83. grid.DataSource = dataSource;
  84. grid.Load += (sender, e) =>
  85. {
  86. grid.HideColumn("UpdateTime");
  87. grid.HideColumn(p => p.FieldName.ToUpper().EndsWith("ID"));
  88. grid.HideColumn(p => p.ColumnType == typeof(List<>));
  89. grid.HideColumn(p => p.ColumnType == typeof(ICollection<>));
  90. grid.HideColumn(p => p.ColumnType.BaseType != null && p.ColumnType.BaseType.Name.Contains("BaseEntity"));
  91. };
  92. grid.MainView.BorderStyle = BorderStyles.Flat;
  93. var view = grid.MainView as GridView;
  94. SetViewDefaultProps(grid, view, rowHeight, showScrollH);
  95. var childView = grid.GetChildView();
  96. if (childView != null)
  97. {
  98. view.OptionsView.ShowDetailButtons = true;
  99. SetViewDefaultProps(grid, childView, rowHeight, showScrollH);
  100. childView.OptionsMenu.EnableColumnMenu = false;
  101. childView.OptionsCustomization.AllowSort = false;
  102. childView.OptionsCustomization.AllowFilter = false;
  103. childView.OptionsCustomization.AllowGroup = false;
  104. }
  105. grid.Tag = new GridTag();
  106. if (formatNullValue)
  107. grid.UseNullValueText();
  108. return grid;
  109. }
  110. public static GridView GetChildView(this GridControl grid)
  111. {
  112. return grid.LevelTree?.Nodes?.FirstOrDefault()?.LevelTemplate as GridView;
  113. }
  114. public static GridControl UseEditForm(this GridControl grid, int columnCount, params string[] columns)
  115. {
  116. var view = grid.MainView as GridView;
  117. view.OptionsBehavior.Editable = true;
  118. view.OptionsBehavior.EditingMode = DevExpress.XtraGrid.Views.Grid.GridEditingMode.EditForm;
  119. //foreach (GridColumn item in view.Columns)
  120. //{
  121. // if (item.VisibleIndex > 0)
  122. // item.OptionsEditForm.VisibleIndex = item.VisibleIndex;
  123. //}
  124. var maxIdx = view.Columns.Max(p => p.OptionsEditForm.VisibleIndex);
  125. for (int i = 0; i < columns.Length; i++)
  126. {
  127. view.Columns[columns[i]].OptionsEditForm.Visible = DefaultBoolean.True;
  128. view.Columns[columns[i]].OptionsEditForm.VisibleIndex = maxIdx + i + 1;
  129. }
  130. return grid;
  131. }
  132. private static void SetViewDefaultProps(GridControl grid, GridView view, int rowHeight, bool showScrollH)
  133. {
  134. view.CustomColumnDisplayText += View_CustomColumnDisplayText;
  135. view.OptionsView.ShowButtonMode = DevExpress.XtraGrid.Views.Base.ShowButtonModeEnum.ShowAlways;
  136. view.Appearance.HeaderPanel.TextOptions.HAlignment = HorzAlignment.Center;
  137. view.Appearance.Row.Options.UseTextOptions = true;
  138. view.Appearance.Row.TextOptions.HAlignment = HorzAlignment.Center;
  139. view.OptionsView.ColumnHeaderAutoHeight = DefaultBoolean.True;
  140. view.RowHeight = rowHeight;
  141. view.OptionsView.ShowGroupPanel = false;
  142. view.OptionsDetail.ShowDetailTabs = false;
  143. view.OptionsDetail.AllowZoomDetail = false;
  144. view.OptionsBehavior.Editable = false;
  145. view.OptionsView.ShowDetailButtons = false;
  146. view.OptionsView.ShowIndicator = false;
  147. view.OptionsMenu.EnableColumnMenu = true;
  148. view.OptionsCustomization.AllowFilter = true;
  149. view.OptionsCustomization.AllowGroup = false;
  150. view.OptionsCustomization.AllowSort = true;
  151. view.OptionsCustomization.AllowColumnMoving = true;
  152. view.OptionsCustomization.AllowMergedGrouping = DefaultBoolean.False;
  153. view.OptionsSelection.MultiSelect = false;
  154. view.OptionsCustomization.AllowRowSizing = false;
  155. view.OptionsCustomization.AllowQuickHideColumns = false;
  156. view.OptionsMenu.EnableGroupPanelMenu = false;
  157. view.OptionsMenu.EnableGroupRowMenu = false;
  158. view.OptionsMenu.EnableFooterMenu = false;
  159. view.OptionsLayout.StoreAllOptions = true;
  160. view.OptionsLayout.StoreAppearance = true;
  161. view.OptionsLayout.StoreDataSettings = true;
  162. view.OptionsLayout.StoreVisualOptions = true;
  163. view.OptionsLayout.StoreFormatRules = true;
  164. view.OptionsView.ColumnAutoWidth = !showScrollH;
  165. view.PopupMenuShowing += View_PopupMenuShowing;
  166. view.OptionsSelection.EnableAppearanceFocusedCell = false;
  167. string GetLayoutName()
  168. {
  169. Control ctrl = null;
  170. if (view.Tag is SearchLookUpEdit searchLookUpEdit)
  171. {
  172. ctrl = searchLookUpEdit;
  173. }
  174. else
  175. {
  176. ctrl = grid;
  177. }
  178. while (ctrl.Parent != null)
  179. {
  180. ctrl = ctrl.Parent;
  181. if (ctrl is UserControl) break;
  182. if (ctrl is Form) break;
  183. }
  184. if (ctrl is not UserControl && ctrl is not Form) return null;
  185. //var props = typeof(T).GetProperties();
  186. //StringBuilder sb = new StringBuilder();
  187. //foreach (var item in props)
  188. //{
  189. // sb.Append(item.Name);
  190. //}
  191. //var md5 = MD5Helper.StrToMD5(sb.ToString());
  192. if (view.Tag is SearchLookUpEdit searchLookUpEdit2)
  193. return $"{ctrl.Name}_{searchLookUpEdit2.Name}";
  194. else
  195. return $"{ctrl.Name}_{grid.Name}_{view.Name}";
  196. }
  197. string name = GetLayoutName();
  198. if (!string.IsNullOrWhiteSpace(name))
  199. {
  200. view.Layout += (sender, e) =>
  201. {
  202. Directory.CreateDirectory("Layout");
  203. if (name == null) return;
  204. (sender as GridView).SaveLayoutToXml($"Layout\\{name}.xml", OptionsLayoutBase.FullLayout);
  205. };
  206. }
  207. if (!string.IsNullOrWhiteSpace(name) && File.Exists($"Layout\\{name}.xml"))
  208. {
  209. view.RestoreLayoutFromXml($"Layout\\{name}.xml", OptionsLayoutBase.FullLayout);
  210. view.ClearColumnsFilter();
  211. view.ClearFindFilter();
  212. view.ClearInHeaderSearchText();
  213. view.ClearSorting();
  214. view.ClearSelection();
  215. }
  216. view.KeyUp += View_KeyUp;
  217. }
  218. /// <summary>
  219. /// 为GirdControl启用右键新增数据的功能
  220. /// </summary>
  221. /// <param name="grid"></param>
  222. /// <param name="emptyText"></param>
  223. /// <returns></returns>
  224. public static GridControl UseEmptyText(this GridControl grid, string emptyText = "暂无数据")
  225. {
  226. if (string.IsNullOrWhiteSpace(emptyText)) return grid;
  227. var view = grid.MainView as GridView;
  228. view.CustomDrawEmptyForeground += (sender, e) =>
  229. {
  230. var s = e.Appearance.CalcTextSize(e.Cache, emptyText, e.Bounds.Width).ToSize();
  231. var x = (e.Bounds.Width - s.Width) / 2;
  232. var y = (e.Bounds.Height - s.Height) / 2;
  233. e.Appearance.ForeColor = Color.Gray;
  234. e.Appearance.DrawString(e.Cache, emptyText, new Rectangle(x, y + 20, s.Width, s.Height));
  235. };
  236. return grid;
  237. }
  238. /// <summary>
  239. /// 为GirdControl启用右键新增数据的功能
  240. /// </summary>
  241. /// <typeparam name="T"></typeparam>
  242. /// <param name="grid"></param>
  243. /// <param name="menuCaption"></param>
  244. /// <param name="callback">一个回调函数,返回新增的数据</param>
  245. /// <returns></returns>
  246. public static GridControl UseAdd<T>(this GridControl grid, Func<T> callback, string menuCaption = "新增")
  247. {
  248. var view = grid.MainView as GridView;
  249. view.CustomDrawEmptyForeground += (sender, e) =>
  250. {
  251. string emptyText = "右键添加";
  252. var s = e.Appearance.CalcTextSize(e.Cache, emptyText, e.Bounds.Width).ToSize();
  253. var x = (e.Bounds.Width - s.Width) / 2;
  254. var y = (e.Bounds.Height - s.Height) / 2;
  255. e.Appearance.ForeColor = Color.Gray;
  256. e.Appearance.DrawString(e.Cache, emptyText, new Rectangle(x, y, s.Width, s.Height));
  257. };
  258. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateAdd(), data =>
  259. {
  260. if (callback != null)
  261. {
  262. var addRow = callback();
  263. if (addRow == null) return;
  264. if (grid.DataSource is List<T> ds)
  265. {
  266. ds.Add(addRow);
  267. }
  268. else if (grid.DataSource is BindingList<T> bl)
  269. {
  270. bl.Add(addRow);
  271. }
  272. view.RefreshData();
  273. }
  274. }, true);
  275. return grid;
  276. }
  277. /// <summary>
  278. /// 为GirdControl启用右键新增数据的功能
  279. /// </summary>
  280. /// <typeparam name="T"></typeparam>
  281. /// <param name="grid"></param>
  282. /// <param name="menuCaption"></param>
  283. /// <param name="callback">一个回调函数,返回新增的数据</param>
  284. /// <returns></returns>
  285. public static GridControl UseAddAsync<T>(this GridControl grid, Func<Task<T>> callback, string menuCaption = "新增")
  286. {
  287. grid.AddContentMenuAsync<T>(menuCaption, DxHelper.SvgHelper.CreateAdd(), async data =>
  288. {
  289. if (callback != null)
  290. {
  291. var addRow = await callback();
  292. if (addRow == null) return;
  293. var view = grid.MainView as GridView;
  294. if (grid.DataSource is List<T> ds)
  295. {
  296. ds.Add(addRow);
  297. }
  298. else if (grid.DataSource is BindingList<T> bl)
  299. {
  300. bl.Add(addRow);
  301. }
  302. view.RefreshData();
  303. }
  304. }, true);
  305. return grid;
  306. }
  307. /// <summary>
  308. /// 为GridControl启用右编辑选中的单行功能
  309. /// </summary>
  310. /// <typeparam name="T"></typeparam>
  311. /// <param name="grid"></param>
  312. /// <param name="menuCaption"></param>
  313. /// <param name="callback"></param>
  314. /// <returns></returns>
  315. public static GridControl UseEdit<T>(this GridControl grid, Func<T, T> callback, string menuCaption = "编辑")
  316. {
  317. grid.AddRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateEdit(), data =>
  318. {
  319. if (callback != null)
  320. {
  321. var newRow = callback(data);
  322. if (newRow == null) return;
  323. var view = grid.MainView as GridView;
  324. if (grid.DataSource is List<T> ds)
  325. {
  326. var idx=ds.IndexOf(data);
  327. ds.Remove(data);
  328. ds.Insert(idx, newRow);
  329. }
  330. else if (grid.DataSource is BindingList<T> bl)
  331. {
  332. var idx = bl.IndexOf(data);
  333. bl.Remove(data);
  334. bl.Insert(idx, newRow);
  335. }
  336. view.RefreshData();
  337. }
  338. }, null);
  339. return grid;
  340. }
  341. /// <summary>
  342. /// 为GridControl启用右编辑选中的单行功能
  343. /// </summary>
  344. /// <typeparam name="T"></typeparam>
  345. /// <param name="grid"></param>
  346. /// <param name="menuCaption"></param>
  347. /// <param name="callback"></param>
  348. /// <returns></returns>
  349. public static GridControl UseEditAsync<T>(this GridControl grid, Func<T, Task<T>> callback, string menuCaption = "编辑")
  350. {
  351. grid.AddRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateEdit(), async data =>
  352. {
  353. if (callback != null)
  354. {
  355. var newRow = await callback(data);
  356. if (newRow == null) return;
  357. var view = grid.MainView as GridView;
  358. if (grid.DataSource is List<T> ds)
  359. {
  360. var idx = ds.IndexOf(data);
  361. ds.Remove(data);
  362. ds.Insert(idx, newRow);
  363. }
  364. else if (grid.DataSource is BindingList<T> bl)
  365. {
  366. var idx = bl.IndexOf(data);
  367. bl.Remove(data);
  368. bl.Insert(idx, newRow);
  369. }
  370. view.RefreshData();
  371. }
  372. }, null);
  373. return grid;
  374. }
  375. /// <summary>
  376. /// 为GridControl启用右删除选中的一行或多行功能(自动启用UseMultiSelect)
  377. /// </summary>
  378. /// <typeparam name="T"></typeparam>
  379. /// <param name="grid"></param>
  380. /// <param name="menuCaption"></param>
  381. /// <param name="action"></param>
  382. /// <returns></returns>
  383. public static GridControl UseDelete<T>(this GridControl grid, Func<List<T>, bool> action = null, string menuCaption = "删除")
  384. {
  385. grid.AddMultRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClose(), data =>
  386. {
  387. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认删除选中的记录?共[{data.Count}]条")) return;
  388. if (action != null)
  389. {
  390. bool succeed = action(data);
  391. if (!succeed) return;
  392. }
  393. var view = grid.MainView as GridView;
  394. view.DeleteSelectedRows();
  395. view.RefreshData();
  396. });
  397. return grid;
  398. }
  399. /// <summary>
  400. /// 为GridControl启用右删除选中的一行或多行功能(自动启用UseMultiSelect)
  401. /// </summary>
  402. /// <typeparam name="T"></typeparam>
  403. /// <param name="grid"></param>
  404. /// <param name="menuCaption"></param>
  405. /// <param name="action"></param>
  406. /// <returns></returns>
  407. public static GridControl UseDeleteAsync<T>(this GridControl grid, Func<List<T>, Task<bool>> action = null, string menuCaption = "删除")
  408. {
  409. grid.AddMultRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClose(), async data =>
  410. {
  411. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认删除选中的记录?共[{data.Count()}]条")) return;
  412. if (action != null)
  413. {
  414. bool succeed = await action(data);
  415. if (!succeed) return;
  416. }
  417. var view = grid.MainView as GridView;
  418. view.DeleteSelectedRows();
  419. view.RefreshData();
  420. });
  421. return grid;
  422. }
  423. /// <summary>
  424. /// 为GirdControl启用右键清除所有数据的功能
  425. /// </summary>
  426. /// <typeparam name="T"></typeparam>
  427. /// <param name="grid"></param>
  428. /// <param name="menuCaption"></param>
  429. /// <param name="action"></param>
  430. /// <returns></returns>
  431. public static GridControl UseClear<T>(this GridControl grid, Func<List<T>, bool> action = null, string menuCaption = "清除")
  432. {
  433. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClear(), data =>
  434. {
  435. if (data == null || data.Count == 0) return;
  436. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认清空所有记录?共[{data.Count}]条")) return;
  437. if (action != null)
  438. {
  439. bool succeed = action(data);
  440. if (!succeed) return;
  441. }
  442. var view = grid.MainView as GridView;
  443. data.Clear();
  444. view.RefreshData();
  445. }, false);
  446. return grid;
  447. }
  448. public static GridControl SetLogImageColumn(this GridControl grid, string columnFieldName, Type enumType)
  449. {
  450. var view = grid.MainView as GridView;
  451. RepositoryItemImageComboBox edit = new RepositoryItemImageComboBox();
  452. edit.AddEnum(enumType);
  453. SvgImageCollection svgImages = new SvgImageCollection();
  454. svgImages.ImageSize = new System.Drawing.Size(20, 20);
  455. svgImages.Add(SvgHelper.CreateInfo());
  456. svgImages.Add(SvgHelper.CreateWarning());
  457. svgImages.Add(SvgHelper.CreateError());
  458. edit.SmallImages = svgImages;
  459. edit.GlyphAlignment = DevExpress.Utils.HorzAlignment.Center;
  460. view.Columns[columnFieldName].ColumnEdit = edit;
  461. view.Columns[columnFieldName].VisibleIndex = 0;
  462. view.Columns[columnFieldName].MaxWidth = 64;
  463. view.Columns[columnFieldName].MinWidth = 64;
  464. return grid;
  465. }
  466. public static GridControl SetStateImageColumn(this GridControl grid, string columnFieldName, Type enumType)
  467. {
  468. var view = grid.MainView as GridView;
  469. RepositoryItemImageComboBox edit = new RepositoryItemImageComboBox();
  470. edit.AddEnum(enumType);
  471. SvgImageCollection svgImages = new SvgImageCollection();
  472. svgImages.ImageSize = new System.Drawing.Size(20, 20);
  473. svgImages.Add(SvgHelper.CreateTskStateStoped());
  474. svgImages.Add(SvgHelper.CreateTskStateWaitToRun());
  475. svgImages.Add(SvgHelper.CreateTskStateRunning());
  476. svgImages.Add(SvgHelper.CreateTskStateStopping());
  477. edit.SmallImages = svgImages;
  478. edit.GlyphAlignment = DevExpress.Utils.HorzAlignment.Center;
  479. view.Columns[columnFieldName].ColumnEdit = edit;
  480. view.Columns[columnFieldName].VisibleIndex = 0;
  481. view.Columns[columnFieldName].MaxWidth = 64;
  482. view.Columns[columnFieldName].MinWidth = 64;
  483. return grid;
  484. }
  485. public static GridControl UseRowFocusedStyle(this GridControl grid)
  486. {
  487. var view = grid.MainView as GridView;
  488. view.OptionsSelection.EnableAppearanceFocusedCell = false;
  489. view.FocusRectStyle = DrawFocusRectStyle.RowFocus;
  490. var childView = grid.GetChildView();
  491. if (childView != null)
  492. {
  493. childView.OptionsSelection.EnableAppearanceFocusedCell = false;
  494. childView.FocusRectStyle = DrawFocusRectStyle.RowFocus;
  495. }
  496. return grid;
  497. }
  498. public static GridControl UseFileChooseColumn(this GridControl grid, string columnFieldName, bool columnCanInput = false)
  499. {
  500. var view = grid.MainView as GridView;
  501. var edit = new RepositoryItemButtonEdit() { AutoHeight = false };
  502. edit.ReadOnly = !columnCanInput;
  503. view.Columns[columnFieldName].Visible = true;
  504. view.Columns[columnFieldName].ColumnEdit = edit;
  505. edit.ButtonClick += (sender, e) =>
  506. {
  507. OpenFileDialog dlg = new OpenFileDialog();
  508. dlg.Title = "文件选择";
  509. dlg.Multiselect = false;
  510. if (dlg.ShowDialog() == DialogResult.OK)
  511. {
  512. view.SetFocusedRowCellValue(columnFieldName, dlg.FileName);
  513. }
  514. };
  515. return grid;
  516. }
  517. public static GridControl UseHttpDownloadColumn(this GridControl grid, string columnFieldName)
  518. {
  519. grid.UseEdit(false);
  520. var view = grid.MainView as GridView;
  521. var edit = new RepositoryItemButtonEdit() { AutoHeight = false, ReadOnly = true };
  522. edit.Buttons[0].Kind = ButtonPredefines.Glyph;
  523. edit.Buttons[0].ToolTip = "下载文件";
  524. edit.TextEditStyle = TextEditStyles.DisableTextEditor;
  525. edit.Buttons[0].ImageOptions.SvgImage = SvgHelper.CreateDownload(width: 12, height: 12);
  526. view.Columns[columnFieldName].OptionsColumn.AllowEdit = true;
  527. view.Columns[columnFieldName].Visible = true;
  528. view.Columns[columnFieldName].ColumnEdit = edit;
  529. edit.ButtonClick += async (sender, e) =>
  530. {
  531. var url = view.GetFocusedRowCellValue(columnFieldName)?.ToString();
  532. if (string.IsNullOrWhiteSpace(url)) return;
  533. var localFile = Path.GetFileName(url);
  534. SaveFileDialog d = new SaveFileDialog();
  535. d.FileName = localFile;
  536. if (d.ShowDialog() == DialogResult.OK)
  537. {
  538. try
  539. {
  540. if (await HttpHelper.DownloadAsync(url, d.FileName))
  541. {
  542. var dir = Path.GetDirectoryName(d.FileName);
  543. System.Diagnostics.Process.Start("explorer.exe", dir);
  544. }
  545. else
  546. {
  547. throw new Exception($"文件下载失败,url={url}");
  548. }
  549. }
  550. catch (Exception ex)
  551. {
  552. throw new Exception($"文件下载失败,url={url}",ex);
  553. }
  554. }
  555. };
  556. return grid;
  557. }
  558. public static GridControl UseBoolColumn(this GridControl grid, string columnFieldName, string trueText = "是", string falseText = "否", GridView view = null)
  559. {
  560. if (view == null)
  561. view = grid.MainView as GridView;
  562. var edit = new RepositoryItemImageComboBox() { AutoHeight = false };
  563. edit.Items.Add(new ImageComboBoxItem(trueText, true));
  564. edit.Items.Add(new ImageComboBoxItem(falseText, false));
  565. edit.ReadOnly = false;
  566. view.Columns[columnFieldName].Visible = true;
  567. view.Columns[columnFieldName].ColumnEdit = edit;
  568. if (columnFieldName == "Enable")
  569. view.Columns[columnFieldName].VisibleIndex = 99;
  570. return grid;
  571. }
  572. public static GridControl UseLookUpEditColumn(this GridControl grid, string columnFieldName, string displayField = "", GridView view = null)
  573. {
  574. if (view == null)
  575. view = grid.MainView as GridView;
  576. var edit = new RepositoryItemLookUpEdit();
  577. edit.AutoHeight = false;
  578. edit.ValueMember = "Id";
  579. edit.DisplayMember = displayField;
  580. edit.NullText = "未知";
  581. view.Columns[columnFieldName].Visible = true;
  582. view.Columns[columnFieldName].ColumnEdit = edit;
  583. return grid;
  584. }
  585. public static GridControl UseButtonEditColumn(this GridControl grid, string columnFieldName, GridView view = null)
  586. {
  587. grid.UseEdit(false);
  588. if (view == null)
  589. view = grid.MainView as GridView;
  590. var edit = new RepositoryItemButtonEdit();
  591. edit.Buttons.Clear();
  592. edit.Buttons.Add(new EditorButton(ButtonPredefines.Glyph) { Caption="Click"});
  593. edit.AutoHeight = false;
  594. edit.TextEditStyle = TextEditStyles.HideTextEditor;
  595. view.Columns[columnFieldName].OptionsColumn.AllowEdit = true;
  596. view.Columns[columnFieldName].Visible = true;
  597. view.Columns[columnFieldName].ColumnEdit = edit;
  598. return grid;
  599. }
  600. public static GridControl UseDateTimeEditColumn(this GridControl grid, string columnFieldName, GridView view = null)
  601. {
  602. if (view == null)
  603. view = grid.MainView as GridView;
  604. var edit = new RepositoryItemDateEdit();
  605. edit.AllowNullInput = DevExpress.Utils.DefaultBoolean.False;
  606. edit.AutoHeight = false;
  607. edit.CalendarTimeEditing = DevExpress.Utils.DefaultBoolean.True;
  608. edit.CalendarTimeProperties.DisplayFormat.FormatString = "HH:mm:ss";
  609. edit.CalendarTimeProperties.DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
  610. edit.CalendarTimeProperties.EditFormat.FormatString = "HH:mm:ss";
  611. edit.CalendarTimeProperties.EditFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
  612. edit.CalendarTimeProperties.MaskSettings.Set("mask", "HH:mm:ss");
  613. edit.DisplayFormat.FormatString = "yyyy-MM-dd HH:mm:ss";
  614. edit.DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
  615. edit.EditFormat.FormatString = "yyyy-MM-dd HH:mm:ss";
  616. edit.EditFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
  617. edit.MaskSettings.Set("mask", "yyyy-MM-dd HH:mm:ss");
  618. view.Columns[columnFieldName].Visible = true;
  619. view.Columns[columnFieldName].ColumnEdit = edit;
  620. return grid;
  621. }
  622. public static void UpdateLookUpEditDataSource<T>(this GridControl grid, string columnFieldName, List<T> dataSource, GridView view = null)
  623. {
  624. if (view == null)
  625. view = grid.MainView as GridView;
  626. var edit = view.Columns[columnFieldName].ColumnEdit as RepositoryItemLookUpEdit;
  627. if (edit != null)
  628. edit.DataSource = dataSource;
  629. }
  630. public static GridControl UseSearchEditColumn<T>(this GridControl grid, string columnFieldName, List<T> editDataSource, string displayField = "This", GridView view = null)
  631. {
  632. if (view == null)
  633. view = grid.MainView as GridView;
  634. var edit = new RepositoryItemSearchLookUpEdit();
  635. SearchLookUpEdit dd;
  636. Control ctrl = grid;
  637. while (ctrl.Parent != null)
  638. {
  639. ctrl = ctrl.Parent;
  640. if (ctrl is UserControl) break;
  641. }
  642. var searchEdit1View = new DevExpress.XtraGrid.Views.Grid.GridView();
  643. searchEdit1View.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus;
  644. searchEdit1View.OptionsSelection.EnableAppearanceFocusedCell = false;
  645. searchEdit1View.OptionsView.ShowGroupPanel = false;
  646. edit.Name = $"{ctrl.Name}_{grid.Name}_{columnFieldName}_SearchEdit";
  647. edit.AutoHeight = false;
  648. edit.PopupView = searchEdit1View;
  649. edit.ValueMember = "Id";
  650. edit.KeyMember = "Id";
  651. edit.DisplayMember = displayField;
  652. edit.UseDefault().SetData(editDataSource);
  653. view.Columns[columnFieldName].Visible = true;
  654. view.Columns[columnFieldName].ColumnEdit = edit;
  655. searchEdit1View.GridControl.UseDefault<T>(null);
  656. return grid;
  657. }
  658. public static GridControl UseSearchEditColumn<T>(this GridControl grid, string columnFieldName, Func<Task<List<T>>> onGetData, string displayField = "This", GridView view = null)
  659. {
  660. if (view == null)
  661. view = grid.MainView as GridView;
  662. var edit = new RepositoryItemSearchLookUpEdit();
  663. edit.DataSource = onGetData().Result;
  664. Control ctrl = grid;
  665. while (ctrl.Parent != null)
  666. {
  667. ctrl = ctrl.Parent;
  668. if (ctrl is UserControl) break;
  669. }
  670. var searchEdit1View = new DevExpress.XtraGrid.Views.Grid.GridView();
  671. searchEdit1View.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus;
  672. searchEdit1View.OptionsSelection.EnableAppearanceFocusedCell = false;
  673. searchEdit1View.OptionsView.ShowGroupPanel = false;
  674. edit.Name = $"{ctrl.Name}_{grid.Name}_{columnFieldName}_SearchEdit";
  675. edit.AutoHeight = false;
  676. edit.PopupView = searchEdit1View;
  677. edit.ValueMember = "Id";
  678. edit.KeyMember = "Id";
  679. edit.DisplayMember = displayField;
  680. edit.UseDefault().SetData(onGetData);
  681. view.Columns[columnFieldName].Visible = true;
  682. view.Columns[columnFieldName].ColumnEdit = edit;
  683. searchEdit1View.GridControl.UseDefault<T>(null);
  684. return grid;
  685. }
  686. /// <summary>
  687. /// 为GirdControl启用右键清除所有数据的功能
  688. /// </summary>
  689. /// <typeparam name="T"></typeparam>
  690. /// <param name="grid"></param>
  691. /// <param name="menuCaption"></param>
  692. /// <param name="action"></param>
  693. /// <returns></returns>
  694. public static GridControl UseClearAsync<T>(this GridControl grid, Func<List<T>, Task<bool>> action = null, string menuCaption = "清除")
  695. {
  696. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClear(), async data =>
  697. {
  698. if (data == null || data.Count == 0) return;
  699. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认清空所有记录?共[{data.Count}]条")) return;
  700. if (action != null)
  701. {
  702. bool succeed = await action(data);
  703. if (!succeed) return;
  704. }
  705. var view = grid.MainView as GridView;
  706. data.Clear();
  707. view.RefreshData();
  708. }, false);
  709. return grid;
  710. }
  711. public static GridControl UseExportCsv(this GridControl grid)
  712. {
  713. GridTag tag = grid.Tag as GridTag;
  714. if (tag.BarM == null)
  715. {
  716. tag.BarM = new BarManager();
  717. tag.BarM.Form = grid;
  718. }
  719. if (tag.PopupMenu == null)
  720. {
  721. tag.PopupMenu = new PopupMenu();
  722. }
  723. PopupMenu popupMenu = tag.PopupMenu;
  724. BarButtonItem item = new BarButtonItem();
  725. item.ItemClick += (sender, e) =>
  726. {
  727. SaveFileDialog dialog = new SaveFileDialog();
  728. dialog.Filter = "csv|*.csv";
  729. if (dialog.ShowDialog() == DialogResult.OK)
  730. {
  731. var view = grid.MainView as GridView;
  732. view.ExportToCsv(dialog.FileName);
  733. }
  734. };
  735. item.ImageOptions.SvgImage = DxHelper.SvgHelper.CreateExportCsv();
  736. item.Caption = "导出(CSV)";
  737. tag.BarM.Items.Add(item);
  738. popupMenu.AddItem(item);
  739. popupMenu.Manager = tag.BarM;
  740. tag.PopupMenu = popupMenu;
  741. return grid;
  742. }
  743. public static GridControl AddMenu(this GridControl grid, string menuText, SvgImage meunImage, Action onClick)
  744. {
  745. GridTag tag = grid.Tag as GridTag;
  746. if (tag.BarM == null)
  747. {
  748. tag.BarM = new BarManager();
  749. tag.BarM.Form = grid;
  750. }
  751. if (tag.PopupMenu == null)
  752. {
  753. tag.PopupMenu = new PopupMenu();
  754. }
  755. PopupMenu popupMenu = tag.PopupMenu;
  756. BarButtonItem item = new BarButtonItem();
  757. item.ItemClick += (sender, e) =>
  758. {
  759. item.Enabled = false;
  760. onClick?.Invoke();
  761. item.Enabled = true;
  762. };
  763. item.ImageOptions.SvgImage = meunImage;
  764. item.Caption = menuText;
  765. tag.BarM.Items.Add(item);
  766. popupMenu.AddItem(item);
  767. popupMenu.Manager = tag.BarM;
  768. tag.PopupMenu = popupMenu;
  769. return grid;
  770. }
  771. public static GridControl UseExportXlsx(this GridControl grid)
  772. {
  773. GridTag tag = grid.Tag as GridTag;
  774. if (tag.BarM == null)
  775. {
  776. tag.BarM = new BarManager();
  777. tag.BarM.Form = grid;
  778. }
  779. if (tag.PopupMenu == null)
  780. {
  781. tag.PopupMenu = new PopupMenu();
  782. }
  783. PopupMenu popupMenu = tag.PopupMenu;
  784. BarButtonItem item = new BarButtonItem();
  785. item.ItemClick += (sender, e) =>
  786. {
  787. SaveFileDialog dialog = new SaveFileDialog();
  788. dialog.Filter = "Excel文件|*.xlsx";
  789. if (dialog.ShowDialog() == DialogResult.OK)
  790. {
  791. var view = grid.MainView as GridView;
  792. view.ExportToXlsx(dialog.FileName);
  793. }
  794. };
  795. item.ImageOptions.SvgImage = DxHelper.SvgHelper.CreateExportXlsx();
  796. item.Caption = "导出(Excel)";
  797. tag.BarM.Items.Add(item);
  798. popupMenu.AddItem(item);
  799. popupMenu.Manager = tag.BarM;
  800. tag.PopupMenu = popupMenu;
  801. return grid;
  802. }
  803. private static void View_KeyUp(object sender, KeyEventArgs e)
  804. {
  805. if (e.Control && e.Shift & e.KeyCode == Keys.C)
  806. {
  807. var view = sender as GridView;
  808. if (view.FocusedColumn == null) return;
  809. var val = view.GetFocusedRowCellDisplayText(view.FocusedColumn);
  810. if (string.IsNullOrWhiteSpace(val)) return;
  811. Clipboard.SetText(val);
  812. }
  813. }
  814. private static void View_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e)
  815. {
  816. if (e.Column.ColumnType == typeof(DateTime) || e.Column.ColumnType == typeof(DateTime?))
  817. {
  818. if (e.Value == null) return;
  819. if (e.Column.ColumnType == typeof(DateTime))
  820. e.DisplayText = Convert.ToDateTime(e.Value).ToString("yyyy-MM-dd HH:mm:ss");
  821. }
  822. }
  823. public static GridControl ShowColumn(this GridControl grid, params string[] colField)
  824. {
  825. var view = grid.MainView as GridView;
  826. if (view.Columns.Count == 0) return grid;
  827. if (colField == null || colField.Length == 0) return grid;
  828. foreach (GridColumn item in view.Columns)
  829. {
  830. if (colField.Contains(item.FieldName))
  831. item.Visible = true;
  832. }
  833. return grid;
  834. }
  835. public static GridControl UseMultiSelect(this GridControl grid, bool useCheckBoxSelect = false)
  836. {
  837. var view = grid.MainView as GridView;
  838. view.OptionsSelection.MultiSelect = true;
  839. if (useCheckBoxSelect)
  840. view.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CheckBoxRowSelect;
  841. else
  842. view.OptionsSelection.MultiSelectMode = GridMultiSelectMode.RowSelect;
  843. return grid;
  844. }
  845. public static GridControl UseGroup(this GridControl grid)
  846. {
  847. var view = grid.MainView as GridView;
  848. view.OptionsView.GroupFooterShowMode = GroupFooterShowMode.Hidden;
  849. view.OptionsView.ShowGroupPanel = true;
  850. view.OptionsCustomization.AllowGroup = true;
  851. view.OptionsCustomization.AllowSort = true;
  852. return grid;
  853. }
  854. public static GridControl UseFooter(this GridControl grid, Action<object, DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgs> act)
  855. {
  856. var view = grid.MainView as GridView;
  857. view.OptionsView.ShowFooter = true;
  858. view.CustomDrawFooter += (s, e) => act(s, e);
  859. return grid;
  860. }
  861. public static GridControl UseEdit(this GridControl grid, bool columnsEdit = false)
  862. {
  863. var view = grid.MainView as GridView;
  864. view.OptionsBehavior.Editable = true;
  865. view.OptionsSelection.EnableAppearanceFocusedCell = true;
  866. foreach (GridColumn item in view.Columns)
  867. {
  868. item.OptionsColumn.AllowEdit = columnsEdit;
  869. }
  870. return grid;
  871. }
  872. public static GridControl UseRowNumber(this GridControl grid)
  873. {
  874. var view = grid.MainView as GridView;
  875. view.OptionsView.ShowIndicator = true;
  876. view.CustomDrawRowIndicator += (s, e) =>
  877. {
  878. if (!e.Info.IsRowIndicator) return;
  879. if (e.RowHandle < 0) return;
  880. e.Handled = true;
  881. string txt = (e.RowHandle + 1).ToString();
  882. var txtSize = e.Graphics.MeasureString(txt, e.Appearance.Font);
  883. if (view.IndicatorWidth < txtSize.Width + 20)
  884. {
  885. view.IndicatorWidth++;
  886. }
  887. var loc = new PointF(e.Bounds.X + e.Bounds.Width / 2f - txtSize.Width / 2f + 2,
  888. e.Bounds.Y + e.Bounds.Height / 2f - txtSize.Height / 2f);
  889. e.Cache.FillRectangle(new SolidBrush(e.Appearance.BackColor), e.Bounds);
  890. e.Cache.DrawString(txt, e.Appearance.Font, new SolidBrush(e.Appearance.ForeColor), loc);
  891. };
  892. view.RowCountChanged += (sender, e) =>
  893. {
  894. if (view.RowCount == 0)
  895. view.IndicatorWidth = -1;
  896. else
  897. view.IndicatorWidth = view.RowCount.ToString().Length * 6 + 20;
  898. };
  899. return grid;
  900. }
  901. private static GridControl UseNullValueText(this GridControl grid, string nullText = "--")
  902. {
  903. var view = grid.MainView as GridView;
  904. view.CustomColumnDisplayText += (sender, e) =>
  905. {
  906. if (e.Value == null || e.Value.ToString().Trim() == "")
  907. e.DisplayText = nullText;
  908. };
  909. return grid;
  910. }
  911. public static GridControl SetDisplayText(this GridControl grid, string columnFieldName, Func<object, string> action)
  912. {
  913. var view = grid.MainView as GridView;
  914. view.CustomColumnDisplayText += (sender, e) =>
  915. {
  916. if (e.Column.FieldName != columnFieldName) return;
  917. if (e.Value == null || action == null) return;
  918. e.DisplayText = action(e.Value);
  919. };
  920. return grid;
  921. }
  922. /// <summary>
  923. /// 隐藏指定字段的列
  924. /// </summary>
  925. /// <param name="grid"></param>
  926. /// <param name="colField"></param>
  927. /// <returns></returns>
  928. public static GridControl HideColumn(this GridControl grid, params string[] colField)
  929. {
  930. colField = colField.Select(t => t.ToLower()).ToArray();
  931. var view = grid.MainView as GridView;
  932. if (colField == null || colField.Length == 0) return grid;
  933. foreach (GridColumn item in view.Columns)
  934. {
  935. if (colField.Contains(item.FieldName.ToLower()))
  936. item.Visible = false;
  937. }
  938. return grid;
  939. }
  940. /// <summary>
  941. /// 根据条件隐藏列(只会处理ColumnEdit==null的列)
  942. /// </summary>
  943. /// <param name="grid"></param>
  944. /// <param name="condition"></param>
  945. /// <returns></returns>
  946. public static GridControl HideColumn(this GridControl grid, Func<GridColumn, bool> condition)
  947. {
  948. var view = grid.MainView as GridView;
  949. foreach (GridColumn item in view.Columns)
  950. {
  951. if (item.ColumnEdit == null && condition(item))
  952. item.Visible = false;
  953. }
  954. return grid;
  955. }
  956. /// <summary>
  957. /// GridControl添加单行元素选择后的右键菜单
  958. /// </summary>
  959. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  960. /// <param name="grid">GridControl控件</param>
  961. /// <param name="menuText">菜单标题</param>
  962. /// <param name="meunImage">菜单图标</param>
  963. /// <param name="action">菜单要执行的事件函数,参数为选中的单行元素</param>
  964. /// <param name="showCondition">菜单显示的条件</param>
  965. /// <returns></returns>
  966. public static GridControl AddRowMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  967. Action<T> action, Func<T, bool> showCondition = null)
  968. {
  969. GridTag tag = grid.Tag as GridTag;
  970. var view = grid.MainView as GridView;
  971. if (tag.BarM == null)
  972. {
  973. tag.BarM = new BarManager();
  974. tag.BarM.Form = grid;
  975. }
  976. if (tag.PopupMenu == null)
  977. {
  978. tag.PopupMenu = new PopupMenu();
  979. }
  980. var popupMenu = tag.PopupMenu;
  981. BarButtonItem item = new BarButtonItem();
  982. tag.RowButtonsItems.Add(item);
  983. Func<bool> showConditionAll = () =>
  984. {
  985. if (!view.GetSelectedRows().Any()) return false;
  986. if (showCondition == null)
  987. return true;
  988. else
  989. return showCondition((T)view.GetFocusedRow());
  990. };
  991. item.Tag = showConditionAll;
  992. var handle = new ItemClickEventHandler((sender, e) =>
  993. {
  994. if (action != null)
  995. {
  996. if (view.GetFocusedRow() == null) return;
  997. item.Enabled = false;
  998. action.Invoke((T)view.GetFocusedRow());
  999. item.Enabled = true;
  1000. }
  1001. });
  1002. item.Events().AddHandler(menuText, handle);
  1003. item.ItemClick += handle;
  1004. item.ImageOptions.SvgImage = meunImage;
  1005. item.Caption = menuText;
  1006. tag.BarM.Items.Add(item);
  1007. popupMenu.AddItem(item);
  1008. popupMenu.Manager = tag.BarM;
  1009. tag.PopupMenu = popupMenu;
  1010. return grid;
  1011. }
  1012. /// <summary>
  1013. /// GridControl添加单行元素选择后的右键菜单
  1014. /// </summary>
  1015. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1016. /// <param name="grid">GridControl控件</param>
  1017. /// <param name="menuText">菜单标题</param>
  1018. /// <param name="meunImage">菜单图标</param>
  1019. /// <param name="action">菜单要执行的异步事件函数,参数为选中的单行元素</param>
  1020. /// <param name="showCondition">菜单显示的条件</param>
  1021. /// <returns></returns>
  1022. public static GridControl AddRowMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1023. Func<T, Task> action, Func<T, bool> showCondition = null)
  1024. {
  1025. GridTag tag = grid.Tag as GridTag;
  1026. var view = grid.MainView as GridView;
  1027. if (tag.BarM == null)
  1028. {
  1029. tag.BarM = new BarManager();
  1030. tag.BarM.Form = grid;
  1031. }
  1032. if (tag.PopupMenu == null)
  1033. {
  1034. tag.PopupMenu = new PopupMenu();
  1035. }
  1036. var popupMenu = tag.PopupMenu;
  1037. BarButtonItem item = new BarButtonItem();
  1038. tag.RowButtonsItems.Add(item);
  1039. Func<bool> showConditionAll = () =>
  1040. {
  1041. if (!view.GetSelectedRows().Any()) return false;
  1042. if (showCondition == null)
  1043. return true;
  1044. else
  1045. return showCondition((T)view.GetFocusedRow());
  1046. };
  1047. item.Tag = showConditionAll;
  1048. var handle = new ItemClickEventHandler(async (sender, e) =>
  1049. {
  1050. if (action != null)
  1051. {
  1052. if (view.GetFocusedRow() == null) return;
  1053. item.Enabled = false;
  1054. await action.Invoke((T)view.GetFocusedRow());
  1055. item.Enabled = true;
  1056. }
  1057. });
  1058. item.Events().AddHandler(menuText, handle);
  1059. item.ItemClick += handle;
  1060. item.ImageOptions.SvgImage = meunImage;
  1061. item.Caption = menuText;
  1062. tag.BarM.Items.Add(item);
  1063. popupMenu.AddItem(item);
  1064. popupMenu.Manager = tag.BarM;
  1065. tag.PopupMenu = popupMenu;
  1066. return grid;
  1067. }
  1068. /// <summary>
  1069. /// GridControl添加多行选择元素的右键菜单(自动启用UseMultiSelect)
  1070. /// </summary>
  1071. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1072. /// <param name="grid">GridControl控件</param>
  1073. /// <param name="menuText">菜单标题</param>
  1074. /// <param name="meunImage">菜单图标</param>
  1075. /// <param name="action">菜单要执行的事件,参数为选中的一行或多行元素</param>
  1076. /// <returns></returns>
  1077. public static GridControl AddMultRowMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1078. Action<List<T>> action)
  1079. {
  1080. grid.UseMultiSelect();
  1081. GridTag tag = grid.Tag as GridTag;
  1082. var view = grid.MainView as GridView;
  1083. if (tag.BarM == null)
  1084. {
  1085. tag.BarM = new BarManager();
  1086. tag.BarM.Form = grid;
  1087. }
  1088. if (tag.PopupMenu == null)
  1089. {
  1090. tag.PopupMenu = new PopupMenu();
  1091. }
  1092. var popupMenu = tag.PopupMenu;
  1093. BarButtonItem item = new BarButtonItem();
  1094. var handle = new ItemClickEventHandler((sender, e) =>
  1095. {
  1096. if (action != null)
  1097. {
  1098. var rows = view.GetSelectedRows();
  1099. List<T> list = new List<T>();
  1100. foreach (var row in rows)
  1101. {
  1102. if (row < 0) continue;
  1103. list.Add((T)view.GetRow(row));
  1104. }
  1105. if (list.Any())
  1106. action.Invoke(list);
  1107. }
  1108. });
  1109. item.Events().AddHandler(menuText, handle);
  1110. item.ItemClick += handle;
  1111. item.ImageOptions.SvgImage = meunImage;
  1112. item.Caption = menuText;
  1113. Func<bool> showCondition = () => view.GetSelectedRows().Any();
  1114. item.Tag = showCondition;
  1115. tag.BarM.Items.Add(item);
  1116. popupMenu.AddItem(item);
  1117. popupMenu.Manager = tag.BarM;
  1118. tag.PopupMenu = popupMenu;
  1119. return grid;
  1120. }
  1121. /// <summary>
  1122. /// GridControl添加多行选择元素的右键菜单(自动启用UseMultiSelect)
  1123. /// </summary>
  1124. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1125. /// <param name="grid">GridControl控件</param>
  1126. /// <param name="menuText">菜单标题</param>
  1127. /// <param name="meunImage">菜单图标</param>
  1128. /// <param name="action">菜单要执行的异步事件函数,参数为选中的一行或多行元素</param>
  1129. /// <returns></returns>
  1130. public static GridControl AddMultRowMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1131. Func<List<T>, Task> action)
  1132. {
  1133. grid.UseMultiSelect();
  1134. GridTag tag = grid.Tag as GridTag;
  1135. var view = grid.MainView as GridView;
  1136. if (tag.BarM == null)
  1137. {
  1138. tag.BarM = new BarManager();
  1139. tag.BarM.Form = grid;
  1140. }
  1141. if (tag.PopupMenu == null)
  1142. {
  1143. tag.PopupMenu = new PopupMenu();
  1144. }
  1145. var popupMenu = tag.PopupMenu;
  1146. BarButtonItem item = new BarButtonItem();
  1147. var handle = new ItemClickEventHandler(async (sender, e) =>
  1148. {
  1149. if (action != null)
  1150. {
  1151. var rows = view.GetSelectedRows();
  1152. List<T> list = new List<T>();
  1153. foreach (var row in rows)
  1154. {
  1155. if (row < 0) continue;
  1156. list.Add((T)view.GetRow(row));
  1157. }
  1158. if (list.Any())
  1159. await action.Invoke(list);
  1160. }
  1161. });
  1162. item.Events().AddHandler(menuText, handle);
  1163. item.ItemClick += handle;
  1164. item.ImageOptions.SvgImage = meunImage;
  1165. item.Caption = menuText;
  1166. Func<bool> showCondition = () => view.GetSelectedRows().Any();
  1167. item.Tag = showCondition;
  1168. tag.BarM.Items.Add(item);
  1169. popupMenu.AddItem(item);
  1170. popupMenu.Manager = tag.BarM;
  1171. tag.PopupMenu = popupMenu;
  1172. return grid;
  1173. }
  1174. /// <summary>
  1175. /// GridControl添加内容区的右键菜单
  1176. /// </summary>
  1177. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1178. /// <param name="grid">GridControl控件</param>
  1179. /// <param name="menuText">菜单标题</param>
  1180. /// <param name="meunImage">菜单图标</param>
  1181. /// <param name="action">菜单要执行的事件,参数为绑定的数据源</param>
  1182. /// <param name="showWithNoneDataRow">内容区没有元素时是否显示此菜单,默认显示</param>
  1183. /// <returns></returns>
  1184. public static GridControl AddContentMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1185. Action<List<T>> action, bool showWithNoneDataRow = true)
  1186. {
  1187. GridTag tag = grid.Tag as GridTag;
  1188. var view = grid.MainView as GridView;
  1189. if (tag.BarM == null)
  1190. {
  1191. tag.BarM = new BarManager();
  1192. tag.BarM.Form = grid;
  1193. }
  1194. if (tag.PopupMenu == null)
  1195. {
  1196. tag.PopupMenu = new PopupMenu();
  1197. }
  1198. var popupMenu = tag.PopupMenu;
  1199. BarButtonItem item = new BarButtonItem();
  1200. var handle = new ItemClickEventHandler((sender, e) =>
  1201. {
  1202. if (action != null)
  1203. {
  1204. if (grid.DataSource is List<T> ds)
  1205. {
  1206. if (!showWithNoneDataRow && (ds == null || ds.Count == 0)) return;
  1207. item.Enabled = false;
  1208. action.Invoke(ds);
  1209. }
  1210. else if (grid.DataSource is BindingList<T> bl)
  1211. {
  1212. if (!showWithNoneDataRow && (bl == null || bl.Count == 0)) return;
  1213. item.Enabled = false;
  1214. action.Invoke(bl.ToList());
  1215. }
  1216. item.Enabled = true;
  1217. }
  1218. });
  1219. item.Events().AddHandler(menuText, handle);
  1220. item.ItemClick += handle;
  1221. item.ImageOptions.SvgImage = meunImage;
  1222. item.Caption = menuText;
  1223. tag.BarM.Items.Add(item);
  1224. popupMenu.AddItem(item);
  1225. popupMenu.Manager = tag.BarM;
  1226. tag.PopupMenu = popupMenu;
  1227. return grid;
  1228. }
  1229. /// <summary>
  1230. /// GridControl添加内容区的右键菜单
  1231. /// </summary>
  1232. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1233. /// <param name="grid">GridControl控件</param>
  1234. /// <param name="menuText">菜单标题</param>
  1235. /// <param name="meunImage">菜单图标</param>
  1236. /// <param name="action">菜单要执行的事件,参数为绑定的数据源</param>
  1237. /// <param name="showWithNoneDataRow">内容区没有元素时是否显示此菜单,默认显示</param>
  1238. /// <returns></returns>
  1239. public static GridControl AddContentMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1240. Func<List<T>, Task> action, bool showWithNoneDataRow = true)
  1241. {
  1242. GridTag tag = grid.Tag as GridTag;
  1243. var view = grid.MainView as GridView;
  1244. if (tag.BarM == null)
  1245. {
  1246. tag.BarM = new BarManager();
  1247. tag.BarM.Form = grid;
  1248. }
  1249. if (tag.PopupMenu == null)
  1250. {
  1251. tag.PopupMenu = new PopupMenu();
  1252. }
  1253. var popupMenu = tag.PopupMenu;
  1254. BarButtonItem item = new BarButtonItem();
  1255. var handle = new ItemClickEventHandler(async (sender, e) =>
  1256. {
  1257. if (action != null)
  1258. {
  1259. if (grid.DataSource is List<T> ds)
  1260. {
  1261. if (!showWithNoneDataRow && (ds == null || ds.Count == 0)) return;
  1262. item.Enabled = false;
  1263. await action.Invoke(ds);
  1264. }
  1265. else if (grid.DataSource is BindingList<T> bl)
  1266. {
  1267. if (!showWithNoneDataRow && (bl == null || bl.Count == 0)) return;
  1268. item.Enabled = false;
  1269. await action.Invoke(bl.ToList());
  1270. }
  1271. item.Enabled = true;
  1272. }
  1273. });
  1274. item.Events().AddHandler(menuText, handle);
  1275. item.ItemClick += handle;
  1276. item.ImageOptions.SvgImage = meunImage;
  1277. item.Caption = menuText;
  1278. tag.BarM.Items.Add(item);
  1279. popupMenu.AddItem(item);
  1280. popupMenu.Manager = tag.BarM;
  1281. tag.PopupMenu = popupMenu;
  1282. return grid;
  1283. }
  1284. private static void View_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e)
  1285. {
  1286. if (e.Menu != null)
  1287. {
  1288. foreach (DXMenuItem item in e.Menu.Items)
  1289. {
  1290. if (!item.Enabled)
  1291. {
  1292. item.Visible = false;
  1293. continue;
  1294. }
  1295. }
  1296. }
  1297. //if (e.HitInfo.HitTest == DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitTest.EmptyRow)
  1298. //{
  1299. // return;
  1300. //}
  1301. var view = sender as GridView;
  1302. var grid = view.GridControl;
  1303. var p = grid.PointToScreen(e.Point);
  1304. var tag = grid.Tag as GridTag;
  1305. if (tag?.PopupMenu != null)
  1306. {
  1307. foreach (BarButtonItemLink item in tag?.PopupMenu?.ItemLinks)
  1308. {
  1309. var buttonItem = item.Item;
  1310. if (buttonItem.Tag != null && buttonItem.Tag is Func<bool> showCondition)
  1311. {
  1312. if (showCondition())
  1313. buttonItem.Visibility = BarItemVisibility.Always;
  1314. else
  1315. buttonItem.Visibility = BarItemVisibility.Never;
  1316. }
  1317. }
  1318. tag?.PopupMenu?.ShowPopup(p);
  1319. }
  1320. }
  1321. public static GridControl DrawGridColumnHeaderCheckBox(this GridControl grid)
  1322. {
  1323. //View的 Editable要为true
  1324. var view = grid.MainView as GridView;
  1325. view.OptionsBehavior.Editable = true;
  1326. view.OptionsSelection.MultiSelect = true;
  1327. view.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CheckBoxRowSelect;
  1328. foreach (GridColumn item in view.Columns)
  1329. {
  1330. item.OptionsColumn.AllowEdit = false;
  1331. }
  1332. return grid;
  1333. }
  1334. }