GridControlEx.cs 54 KB

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