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 UseDelete<T>(this GridControl grid, Func<List<T>, bool> action = null, string menuCaption = "删除")
  385. {
  386. grid.AddMultRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClose(), data =>
  387. {
  388. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认删除选中的记录?共[{data.Count}]条")) return;
  389. if (action != null)
  390. {
  391. bool succeed = action(data);
  392. if (!succeed) return;
  393. }
  394. var view = grid.MainView as GridView;
  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.RefreshData();
  419. });
  420. return grid;
  421. }
  422. /// <summary>
  423. /// 为GirdControl启用右键清除所有数据的功能
  424. /// </summary>
  425. /// <typeparam name="T"></typeparam>
  426. /// <param name="grid"></param>
  427. /// <param name="menuCaption"></param>
  428. /// <param name="action"></param>
  429. /// <returns></returns>
  430. public static GridControl UseClear<T>(this GridControl grid, Func<List<T>, bool> action = null, string menuCaption = "清除")
  431. {
  432. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClear(), data =>
  433. {
  434. if (data == null || data.Count == 0) return;
  435. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认清空所有记录?共[{data.Count}]条")) return;
  436. if (action != null)
  437. {
  438. bool succeed = action(data);
  439. if (!succeed) return;
  440. }
  441. var view = grid.MainView as GridView;
  442. data.Clear();
  443. view.RefreshData();
  444. }, false);
  445. return grid;
  446. }
  447. public static GridControl SetLogImageColumn(this GridControl grid, string columnFieldName, Type enumType)
  448. {
  449. var view = grid.MainView as GridView;
  450. RepositoryItemImageComboBox edit = new RepositoryItemImageComboBox();
  451. edit.AddEnum(enumType);
  452. SvgImageCollection svgImages = new SvgImageCollection();
  453. svgImages.ImageSize = new System.Drawing.Size(20, 20);
  454. svgImages.Add(SvgHelper.CreateInfo());
  455. svgImages.Add(SvgHelper.CreateWarning());
  456. svgImages.Add(SvgHelper.CreateError());
  457. edit.SmallImages = svgImages;
  458. edit.GlyphAlignment = DevExpress.Utils.HorzAlignment.Center;
  459. view.Columns[columnFieldName].ColumnEdit = edit;
  460. view.Columns[columnFieldName].VisibleIndex = 0;
  461. view.Columns[columnFieldName].MaxWidth = 64;
  462. view.Columns[columnFieldName].MinWidth = 64;
  463. return grid;
  464. }
  465. public static GridControl SetStateImageColumn(this GridControl grid, string columnFieldName, Type enumType)
  466. {
  467. var view = grid.MainView as GridView;
  468. RepositoryItemImageComboBox edit = new RepositoryItemImageComboBox();
  469. edit.AddEnum(enumType);
  470. SvgImageCollection svgImages = new SvgImageCollection();
  471. svgImages.ImageSize = new System.Drawing.Size(20, 20);
  472. svgImages.Add(SvgHelper.CreateTskStateStoped());
  473. svgImages.Add(SvgHelper.CreateTskStateWaitToRun());
  474. svgImages.Add(SvgHelper.CreateTskStateRunning());
  475. svgImages.Add(SvgHelper.CreateTskStateStopping());
  476. edit.SmallImages = svgImages;
  477. edit.GlyphAlignment = DevExpress.Utils.HorzAlignment.Center;
  478. view.Columns[columnFieldName].ColumnEdit = edit;
  479. view.Columns[columnFieldName].VisibleIndex = 0;
  480. view.Columns[columnFieldName].MaxWidth = 64;
  481. view.Columns[columnFieldName].MinWidth = 64;
  482. return grid;
  483. }
  484. public static GridControl UseRowFocusedStyle(this GridControl grid)
  485. {
  486. var view = grid.MainView as GridView;
  487. view.OptionsSelection.EnableAppearanceFocusedCell = false;
  488. view.FocusRectStyle = DrawFocusRectStyle.RowFocus;
  489. var childView = grid.GetChildView();
  490. if (childView != null)
  491. {
  492. childView.OptionsSelection.EnableAppearanceFocusedCell = false;
  493. childView.FocusRectStyle = DrawFocusRectStyle.RowFocus;
  494. }
  495. return grid;
  496. }
  497. public static GridControl UseFileChooseColumn(this GridControl grid, string columnFieldName, bool columnCanInput = false)
  498. {
  499. var view = grid.MainView as GridView;
  500. var edit = new RepositoryItemButtonEdit() { AutoHeight = false };
  501. edit.ReadOnly = !columnCanInput;
  502. view.Columns[columnFieldName].Visible = true;
  503. view.Columns[columnFieldName].ColumnEdit = edit;
  504. edit.ButtonClick += (sender, e) =>
  505. {
  506. OpenFileDialog dlg = new OpenFileDialog();
  507. dlg.Title = "文件选择";
  508. dlg.Multiselect = false;
  509. if (dlg.ShowDialog() == DialogResult.OK)
  510. {
  511. view.SetFocusedRowCellValue(columnFieldName, dlg.FileName);
  512. }
  513. };
  514. return grid;
  515. }
  516. public static GridControl UseHttpDownloadColumn(this GridControl grid, string columnFieldName)
  517. {
  518. grid.UseEdit(false);
  519. var view = grid.MainView as GridView;
  520. var edit = new RepositoryItemButtonEdit() { AutoHeight = false, ReadOnly = true };
  521. edit.Buttons[0].Kind = ButtonPredefines.Glyph;
  522. edit.Buttons[0].ToolTip = "下载文件";
  523. edit.TextEditStyle = TextEditStyles.DisableTextEditor;
  524. edit.Buttons[0].ImageOptions.SvgImage = SvgHelper.CreateDownload(width: 12, height: 12);
  525. view.Columns[columnFieldName].OptionsColumn.AllowEdit = true;
  526. view.Columns[columnFieldName].Visible = true;
  527. view.Columns[columnFieldName].ColumnEdit = edit;
  528. edit.ButtonClick += async (sender, e) =>
  529. {
  530. var url = view.GetFocusedRowCellValue(columnFieldName)?.ToString();
  531. if (string.IsNullOrWhiteSpace(url)) return;
  532. var localFile = Path.GetFileName(url);
  533. SaveFileDialog d = new SaveFileDialog();
  534. d.FileName = localFile;
  535. if (d.ShowDialog() == DialogResult.OK)
  536. {
  537. try
  538. {
  539. if (await HttpHelper.DownloadAsync(url, d.FileName))
  540. {
  541. var dir = Path.GetDirectoryName(d.FileName);
  542. System.Diagnostics.Process.Start("explorer.exe", dir);
  543. }
  544. else
  545. {
  546. throw new Exception($"文件下载失败,url={url}");
  547. }
  548. }
  549. catch (Exception ex)
  550. {
  551. throw new Exception($"文件下载失败,url={url}", ex);
  552. }
  553. }
  554. };
  555. return grid;
  556. }
  557. public static GridControl UseBoolColumn(this GridControl grid, string columnFieldName, string trueText = "是", string falseText = "否", GridView view = null)
  558. {
  559. if (view == null)
  560. view = grid.MainView as GridView;
  561. var edit = new RepositoryItemImageComboBox() { AutoHeight = false };
  562. edit.Items.Add(new ImageComboBoxItem(trueText, true));
  563. edit.Items.Add(new ImageComboBoxItem(falseText, false));
  564. edit.ReadOnly = false;
  565. view.Columns[columnFieldName].Visible = true;
  566. view.Columns[columnFieldName].ColumnEdit = edit;
  567. if (columnFieldName == "Enable")
  568. view.Columns[columnFieldName].VisibleIndex = 99;
  569. return grid;
  570. }
  571. public static GridControl UseLookUpEditColumn(this GridControl grid, string columnFieldName, string displayField = "", GridView view = null)
  572. {
  573. if (view == null)
  574. view = grid.MainView as GridView;
  575. var edit = new RepositoryItemLookUpEdit();
  576. edit.AutoHeight = false;
  577. edit.ValueMember = "Id";
  578. edit.DisplayMember = displayField;
  579. edit.NullText = "未知";
  580. view.Columns[columnFieldName].Visible = true;
  581. view.Columns[columnFieldName].ColumnEdit = edit;
  582. return grid;
  583. }
  584. public static GridControl UseButtonEditColumn(this GridControl grid, string columnFieldName, GridView view = null)
  585. {
  586. grid.UseEdit(false);
  587. if (view == null)
  588. view = grid.MainView as GridView;
  589. var edit = new RepositoryItemButtonEdit();
  590. edit.Buttons.Clear();
  591. edit.Buttons.Add(new EditorButton(ButtonPredefines.Glyph) { Caption = "Click" });
  592. edit.AutoHeight = false;
  593. edit.TextEditStyle = TextEditStyles.HideTextEditor;
  594. view.Columns[columnFieldName].OptionsColumn.AllowEdit = true;
  595. view.Columns[columnFieldName].Visible = true;
  596. view.Columns[columnFieldName].ColumnEdit = edit;
  597. return grid;
  598. }
  599. public static GridControl UseDateTimeEditColumn(this GridControl grid, string columnFieldName, GridView view = null)
  600. {
  601. if (view == null)
  602. view = grid.MainView as GridView;
  603. var edit = new RepositoryItemDateEdit();
  604. edit.AllowNullInput = DevExpress.Utils.DefaultBoolean.False;
  605. edit.AutoHeight = false;
  606. edit.CalendarTimeEditing = DevExpress.Utils.DefaultBoolean.True;
  607. edit.CalendarTimeProperties.DisplayFormat.FormatString = "HH:mm:ss";
  608. edit.CalendarTimeProperties.DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
  609. edit.CalendarTimeProperties.EditFormat.FormatString = "HH:mm:ss";
  610. edit.CalendarTimeProperties.EditFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
  611. edit.CalendarTimeProperties.MaskSettings.Set("mask", "HH:mm:ss");
  612. edit.DisplayFormat.FormatString = "yyyy-MM-dd HH:mm:ss";
  613. edit.DisplayFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
  614. edit.EditFormat.FormatString = "yyyy-MM-dd HH:mm:ss";
  615. edit.EditFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
  616. edit.MaskSettings.Set("mask", "yyyy-MM-dd HH:mm:ss");
  617. view.Columns[columnFieldName].Visible = true;
  618. view.Columns[columnFieldName].ColumnEdit = edit;
  619. return grid;
  620. }
  621. public static void UpdateLookUpEditDataSource<T>(this GridControl grid, string columnFieldName, List<T> dataSource, GridView view = null)
  622. {
  623. if (view == null)
  624. view = grid.MainView as GridView;
  625. var edit = view.Columns[columnFieldName].ColumnEdit as RepositoryItemLookUpEdit;
  626. if (edit != null)
  627. edit.DataSource = dataSource;
  628. }
  629. public static GridControl UseSearchEditColumn<T>(this GridControl grid, string columnFieldName, List<T> editDataSource, string displayField = "This", GridView view = null)
  630. {
  631. if (view == null)
  632. view = grid.MainView as GridView;
  633. var edit = new RepositoryItemSearchLookUpEdit();
  634. SearchLookUpEdit dd;
  635. Control ctrl = grid;
  636. while (ctrl.Parent != null)
  637. {
  638. ctrl = ctrl.Parent;
  639. if (ctrl is UserControl) break;
  640. }
  641. var searchEdit1View = new DevExpress.XtraGrid.Views.Grid.GridView();
  642. searchEdit1View.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus;
  643. searchEdit1View.OptionsSelection.EnableAppearanceFocusedCell = false;
  644. searchEdit1View.OptionsView.ShowGroupPanel = false;
  645. edit.Name = $"{ctrl.Name}_{grid.Name}_{columnFieldName}_SearchEdit";
  646. edit.AutoHeight = false;
  647. edit.PopupView = searchEdit1View;
  648. edit.ValueMember = "Id";
  649. edit.KeyMember = "Id";
  650. edit.DisplayMember = displayField;
  651. edit.UseDefault().SetData(editDataSource);
  652. view.Columns[columnFieldName].Visible = true;
  653. view.Columns[columnFieldName].ColumnEdit = edit;
  654. searchEdit1View.GridControl.UseDefault<T>(null);
  655. return grid;
  656. }
  657. public static GridControl UseSearchEditColumn<T>(this GridControl grid, string columnFieldName, Func<Task<List<T>>> onGetData, string displayField = "This", GridView view = null)
  658. {
  659. if (view == null)
  660. view = grid.MainView as GridView;
  661. var edit = new RepositoryItemSearchLookUpEdit();
  662. edit.DataSource = onGetData().Result;
  663. Control ctrl = grid;
  664. while (ctrl.Parent != null)
  665. {
  666. ctrl = ctrl.Parent;
  667. if (ctrl is UserControl) break;
  668. }
  669. var searchEdit1View = new DevExpress.XtraGrid.Views.Grid.GridView();
  670. searchEdit1View.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus;
  671. searchEdit1View.OptionsSelection.EnableAppearanceFocusedCell = false;
  672. searchEdit1View.OptionsView.ShowGroupPanel = false;
  673. edit.Name = $"{ctrl.Name}_{grid.Name}_{columnFieldName}_SearchEdit";
  674. edit.AutoHeight = false;
  675. edit.PopupView = searchEdit1View;
  676. edit.ValueMember = "Id";
  677. edit.KeyMember = "Id";
  678. edit.DisplayMember = displayField;
  679. edit.UseDefault().SetData(onGetData);
  680. view.Columns[columnFieldName].Visible = true;
  681. view.Columns[columnFieldName].ColumnEdit = edit;
  682. searchEdit1View.GridControl.UseDefault<T>(null);
  683. return grid;
  684. }
  685. /// <summary>
  686. /// 为GirdControl启用右键清除所有数据的功能
  687. /// </summary>
  688. /// <typeparam name="T"></typeparam>
  689. /// <param name="grid"></param>
  690. /// <param name="menuCaption"></param>
  691. /// <param name="action"></param>
  692. /// <returns></returns>
  693. public static GridControl UseClearAsync<T>(this GridControl grid, Func<Task<bool>> action = null, string menuCaption = "清除")
  694. {
  695. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClear(), async data =>
  696. {
  697. if (data == null || data.Count == 0) return;
  698. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认清空所有记录?")) return;
  699. if (action != null)
  700. {
  701. bool succeed = await action();
  702. if (!succeed) return;
  703. }
  704. var view = grid.MainView as GridView;
  705. data.Clear();
  706. view.RefreshData();
  707. }, false);
  708. return grid;
  709. }
  710. public static GridControl UseExportCsv(this GridControl grid)
  711. {
  712. GridTag tag = grid.Tag as GridTag;
  713. if (tag.BarM == null)
  714. {
  715. tag.BarM = new BarManager();
  716. tag.BarM.Form = grid;
  717. }
  718. if (tag.PopupMenu == null)
  719. {
  720. tag.PopupMenu = new PopupMenu();
  721. }
  722. PopupMenu popupMenu = tag.PopupMenu;
  723. BarButtonItem item = new BarButtonItem();
  724. item.ItemClick += (sender, e) =>
  725. {
  726. SaveFileDialog dialog = new SaveFileDialog();
  727. dialog.Filter = "csv|*.csv";
  728. if (dialog.ShowDialog() == DialogResult.OK)
  729. {
  730. var view = grid.MainView as GridView;
  731. view.ExportToCsv(dialog.FileName);
  732. }
  733. };
  734. item.ImageOptions.SvgImage = DxHelper.SvgHelper.CreateExportCsv();
  735. item.Caption = "导出(CSV)";
  736. tag.BarM.Items.Add(item);
  737. popupMenu.AddItem(item);
  738. popupMenu.Manager = tag.BarM;
  739. tag.PopupMenu = popupMenu;
  740. return grid;
  741. }
  742. public static GridControl AddMenu(this GridControl grid, string menuText, SvgImage meunImage, Action onClick)
  743. {
  744. GridTag tag = grid.Tag as GridTag;
  745. if (tag.BarM == null)
  746. {
  747. tag.BarM = new BarManager();
  748. tag.BarM.Form = grid;
  749. }
  750. if (tag.PopupMenu == null)
  751. {
  752. tag.PopupMenu = new PopupMenu();
  753. }
  754. PopupMenu popupMenu = tag.PopupMenu;
  755. BarButtonItem item = new BarButtonItem();
  756. item.ItemClick += (sender, e) =>
  757. {
  758. item.Enabled = false;
  759. onClick?.Invoke();
  760. item.Enabled = true;
  761. };
  762. item.ImageOptions.SvgImage = meunImage;
  763. item.Caption = menuText;
  764. tag.BarM.Items.Add(item);
  765. popupMenu.AddItem(item);
  766. popupMenu.Manager = tag.BarM;
  767. tag.PopupMenu = popupMenu;
  768. return grid;
  769. }
  770. public static GridControl UseExportXlsx(this GridControl grid)
  771. {
  772. GridTag tag = grid.Tag as GridTag;
  773. if (tag.BarM == null)
  774. {
  775. tag.BarM = new BarManager();
  776. tag.BarM.Form = grid;
  777. }
  778. if (tag.PopupMenu == null)
  779. {
  780. tag.PopupMenu = new PopupMenu();
  781. }
  782. PopupMenu popupMenu = tag.PopupMenu;
  783. BarButtonItem item = new BarButtonItem();
  784. item.ItemClick += (sender, e) =>
  785. {
  786. SaveFileDialog dialog = new SaveFileDialog();
  787. dialog.Filter = "Excel文件|*.xlsx";
  788. if (dialog.ShowDialog() == DialogResult.OK)
  789. {
  790. var view = grid.MainView as GridView;
  791. view.ExportToXlsx(dialog.FileName);
  792. }
  793. };
  794. item.ImageOptions.SvgImage = DxHelper.SvgHelper.CreateExportXlsx();
  795. item.Caption = "导出(Excel)";
  796. tag.BarM.Items.Add(item);
  797. popupMenu.AddItem(item);
  798. popupMenu.Manager = tag.BarM;
  799. tag.PopupMenu = popupMenu;
  800. return grid;
  801. }
  802. private static void View_KeyUp(object sender, KeyEventArgs e)
  803. {
  804. if (e.Control && e.Shift & e.KeyCode == Keys.C)
  805. {
  806. var view = sender as GridView;
  807. if (view.FocusedColumn == null) return;
  808. var val = view.GetFocusedRowCellDisplayText(view.FocusedColumn);
  809. if (string.IsNullOrWhiteSpace(val)) return;
  810. Clipboard.SetText(val);
  811. }
  812. }
  813. private static void View_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e)
  814. {
  815. if (e.Column.ColumnType == typeof(DateTime) || e.Column.ColumnType == typeof(DateTime?))
  816. {
  817. if (e.Value == null) return;
  818. if (e.Column.ColumnType == typeof(DateTime))
  819. e.DisplayText = Convert.ToDateTime(e.Value).ToString("yyyy-MM-dd HH:mm:ss");
  820. }
  821. }
  822. public static GridControl ShowColumn(this GridControl grid, params string[] colField)
  823. {
  824. var view = grid.MainView as GridView;
  825. if (view.Columns.Count == 0) return grid;
  826. if (colField == null || colField.Length == 0) return grid;
  827. foreach (GridColumn item in view.Columns)
  828. {
  829. if (colField.Contains(item.FieldName))
  830. item.Visible = true;
  831. }
  832. return grid;
  833. }
  834. public static GridControl UseMultiSelect(this GridControl grid, bool useCheckBoxSelect = false)
  835. {
  836. var view = grid.MainView as GridView;
  837. view.OptionsSelection.MultiSelect = true;
  838. if (useCheckBoxSelect)
  839. view.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CheckBoxRowSelect;
  840. else
  841. view.OptionsSelection.MultiSelectMode = GridMultiSelectMode.RowSelect;
  842. return grid;
  843. }
  844. public static GridControl UseGroup(this GridControl grid)
  845. {
  846. var view = grid.MainView as GridView;
  847. view.OptionsView.GroupFooterShowMode = GroupFooterShowMode.Hidden;
  848. view.OptionsView.ShowGroupPanel = true;
  849. view.OptionsCustomization.AllowGroup = true;
  850. view.OptionsCustomization.AllowSort = true;
  851. return grid;
  852. }
  853. public static GridControl UseFooter(this GridControl grid, Action<object, DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgs> act)
  854. {
  855. var view = grid.MainView as GridView;
  856. view.OptionsView.ShowFooter = true;
  857. view.CustomDrawFooter += (s, e) => act(s, e);
  858. return grid;
  859. }
  860. public static GridControl UseEdit(this GridControl grid, bool columnsEdit = false)
  861. {
  862. var view = grid.MainView as GridView;
  863. view.OptionsBehavior.Editable = true;
  864. view.OptionsSelection.EnableAppearanceFocusedCell = true;
  865. foreach (GridColumn item in view.Columns)
  866. {
  867. item.OptionsColumn.AllowEdit = columnsEdit;
  868. }
  869. return grid;
  870. }
  871. public static GridControl UseRowNumber(this GridControl grid)
  872. {
  873. var view = grid.MainView as GridView;
  874. view.OptionsView.ShowIndicator = true;
  875. view.CustomDrawRowIndicator += (s, e) =>
  876. {
  877. if (!e.Info.IsRowIndicator) return;
  878. if (e.RowHandle < 0) return;
  879. e.Handled = true;
  880. string txt = (e.RowHandle + 1).ToString();
  881. var txtSize = e.Graphics.MeasureString(txt, e.Appearance.Font);
  882. if (view.IndicatorWidth < txtSize.Width + 20)
  883. {
  884. view.IndicatorWidth++;
  885. }
  886. var loc = new PointF(e.Bounds.X + e.Bounds.Width / 2f - txtSize.Width / 2f + 2,
  887. e.Bounds.Y + e.Bounds.Height / 2f - txtSize.Height / 2f);
  888. e.Cache.FillRectangle(new SolidBrush(e.Appearance.BackColor), e.Bounds);
  889. e.Cache.DrawString(txt, e.Appearance.Font, new SolidBrush(e.Appearance.ForeColor), loc);
  890. };
  891. view.RowCountChanged += (sender, e) =>
  892. {
  893. if (view.RowCount == 0)
  894. view.IndicatorWidth = -1;
  895. else
  896. view.IndicatorWidth = view.RowCount.ToString().Length * 6 + 20;
  897. };
  898. return grid;
  899. }
  900. private static GridControl UseNullValueText(this GridControl grid, string nullText = "--")
  901. {
  902. var view = grid.MainView as GridView;
  903. view.CustomColumnDisplayText += (sender, e) =>
  904. {
  905. if (e.Value == null || e.Value.ToString().Trim() == "")
  906. e.DisplayText = nullText;
  907. };
  908. return grid;
  909. }
  910. public static GridControl SetDisplayText(this GridControl grid, string columnFieldName, Func<object, string> action)
  911. {
  912. var view = grid.MainView as GridView;
  913. view.CustomColumnDisplayText += (sender, e) =>
  914. {
  915. if (e.Column.FieldName != columnFieldName) return;
  916. if (e.Value == null || action == null) return;
  917. e.DisplayText = action(e.Value);
  918. };
  919. return grid;
  920. }
  921. /// <summary>
  922. /// 隐藏指定字段的列
  923. /// </summary>
  924. /// <param name="grid"></param>
  925. /// <param name="colField"></param>
  926. /// <returns></returns>
  927. public static GridControl HideColumn(this GridControl grid, params string[] colField)
  928. {
  929. colField = colField.Select(t => t.ToLower()).ToArray();
  930. var view = grid.MainView as GridView;
  931. if (colField == null || colField.Length == 0) return grid;
  932. foreach (GridColumn item in view.Columns)
  933. {
  934. if (colField.Contains(item.FieldName.ToLower()))
  935. item.Visible = false;
  936. }
  937. return grid;
  938. }
  939. /// <summary>
  940. /// 根据条件隐藏列(只会处理ColumnEdit==null的列)
  941. /// </summary>
  942. /// <param name="grid"></param>
  943. /// <param name="condition"></param>
  944. /// <returns></returns>
  945. public static GridControl HideColumn(this GridControl grid, Func<GridColumn, bool> condition)
  946. {
  947. var view = grid.MainView as GridView;
  948. foreach (GridColumn item in view.Columns)
  949. {
  950. if (item.ColumnEdit == null && condition(item))
  951. item.Visible = false;
  952. }
  953. return grid;
  954. }
  955. /// <summary>
  956. /// 根据条件隐藏列(只会处理ColumnEdit==null的列)
  957. /// </summary>
  958. /// <param name="grid"></param>
  959. /// <param name="condition"></param>
  960. /// <returns></returns>
  961. public static GridControl SetColumnVisibleIndex(this GridControl grid,string fieldName, int idx)
  962. {
  963. var view = grid.MainView as GridView;
  964. foreach (GridColumn item in view.Columns)
  965. {
  966. if (item.FieldName.ToUpper() == fieldName.ToUpper())
  967. {
  968. item.VisibleIndex = idx;
  969. break;
  970. }
  971. }
  972. return grid;
  973. }
  974. /// <summary>
  975. /// GridControl添加单行元素选择后的右键菜单
  976. /// </summary>
  977. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  978. /// <param name="grid">GridControl控件</param>
  979. /// <param name="menuText">菜单标题</param>
  980. /// <param name="meunImage">菜单图标</param>
  981. /// <param name="action">菜单要执行的事件函数,参数为选中的单行元素</param>
  982. /// <param name="showCondition">菜单显示的条件</param>
  983. /// <returns></returns>
  984. public static GridControl AddRowMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  985. Action<T> action, Func<T, bool> showCondition = null)
  986. {
  987. GridTag tag = grid.Tag as GridTag;
  988. var view = grid.MainView as GridView;
  989. if (tag.BarM == null)
  990. {
  991. tag.BarM = new BarManager();
  992. tag.BarM.Form = grid;
  993. }
  994. if (tag.PopupMenu == null)
  995. {
  996. tag.PopupMenu = new PopupMenu();
  997. }
  998. var popupMenu = tag.PopupMenu;
  999. BarButtonItem item = new BarButtonItem();
  1000. tag.RowButtonsItems.Add(item);
  1001. Func<bool> showConditionAll = () =>
  1002. {
  1003. if (!view.GetSelectedRows().Any()) return false;
  1004. if (showCondition == null)
  1005. return true;
  1006. else
  1007. return showCondition((T)view.GetFocusedRow());
  1008. };
  1009. item.Tag = showConditionAll;
  1010. var handle = new ItemClickEventHandler((sender, e) =>
  1011. {
  1012. if (action != null)
  1013. {
  1014. if (view.GetFocusedRow() == null) return;
  1015. item.Enabled = false;
  1016. action.Invoke((T)view.GetFocusedRow());
  1017. item.Enabled = true;
  1018. }
  1019. });
  1020. item.Events().AddHandler(menuText, handle);
  1021. item.ItemClick += handle;
  1022. item.ImageOptions.SvgImage = meunImage;
  1023. item.Caption = menuText;
  1024. tag.BarM.Items.Add(item);
  1025. popupMenu.AddItem(item);
  1026. popupMenu.Manager = tag.BarM;
  1027. tag.PopupMenu = popupMenu;
  1028. return grid;
  1029. }
  1030. /// <summary>
  1031. /// GridControl添加单行元素选择后的右键菜单
  1032. /// </summary>
  1033. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1034. /// <param name="grid">GridControl控件</param>
  1035. /// <param name="menuText">菜单标题</param>
  1036. /// <param name="meunImage">菜单图标</param>
  1037. /// <param name="action">菜单要执行的异步事件函数,参数为选中的单行元素</param>
  1038. /// <param name="showCondition">菜单显示的条件</param>
  1039. /// <returns></returns>
  1040. public static GridControl AddRowMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1041. Func<T, Task> action, Func<T, bool> showCondition = null)
  1042. {
  1043. GridTag tag = grid.Tag as GridTag;
  1044. var view = grid.MainView as GridView;
  1045. if (tag.BarM == null)
  1046. {
  1047. tag.BarM = new BarManager();
  1048. tag.BarM.Form = grid;
  1049. }
  1050. if (tag.PopupMenu == null)
  1051. {
  1052. tag.PopupMenu = new PopupMenu();
  1053. }
  1054. var popupMenu = tag.PopupMenu;
  1055. BarButtonItem item = new BarButtonItem();
  1056. tag.RowButtonsItems.Add(item);
  1057. Func<bool> showConditionAll = () =>
  1058. {
  1059. if (!view.GetSelectedRows().Any()) return false;
  1060. if (showCondition == null)
  1061. return true;
  1062. else
  1063. return showCondition((T)view.GetFocusedRow());
  1064. };
  1065. item.Tag = showConditionAll;
  1066. var handle = new ItemClickEventHandler(async (sender, e) =>
  1067. {
  1068. if (action != null)
  1069. {
  1070. if (view.GetFocusedRow() == null) return;
  1071. item.Enabled = false;
  1072. await action.Invoke((T)view.GetFocusedRow());
  1073. item.Enabled = true;
  1074. }
  1075. });
  1076. item.Events().AddHandler(menuText, handle);
  1077. item.ItemClick += handle;
  1078. item.ImageOptions.SvgImage = meunImage;
  1079. item.Caption = menuText;
  1080. tag.BarM.Items.Add(item);
  1081. popupMenu.AddItem(item);
  1082. popupMenu.Manager = tag.BarM;
  1083. tag.PopupMenu = popupMenu;
  1084. return grid;
  1085. }
  1086. /// <summary>
  1087. /// GridControl添加多行选择元素的右键菜单(自动启用UseMultiSelect)
  1088. /// </summary>
  1089. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1090. /// <param name="grid">GridControl控件</param>
  1091. /// <param name="menuText">菜单标题</param>
  1092. /// <param name="meunImage">菜单图标</param>
  1093. /// <param name="action">菜单要执行的事件,参数为选中的一行或多行元素</param>
  1094. /// <returns></returns>
  1095. public static GridControl AddMultRowMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1096. Action<List<T>> action)
  1097. {
  1098. grid.UseMultiSelect();
  1099. GridTag tag = grid.Tag as GridTag;
  1100. var view = grid.MainView as GridView;
  1101. if (tag.BarM == null)
  1102. {
  1103. tag.BarM = new BarManager();
  1104. tag.BarM.Form = grid;
  1105. }
  1106. if (tag.PopupMenu == null)
  1107. {
  1108. tag.PopupMenu = new PopupMenu();
  1109. }
  1110. var popupMenu = tag.PopupMenu;
  1111. BarButtonItem item = new BarButtonItem();
  1112. var handle = new ItemClickEventHandler((sender, e) =>
  1113. {
  1114. if (action != null)
  1115. {
  1116. var rows = view.GetSelectedRows();
  1117. List<T> list = new List<T>();
  1118. foreach (var row in rows)
  1119. {
  1120. if (row < 0) continue;
  1121. list.Add((T)view.GetRow(row));
  1122. }
  1123. if (list.Any())
  1124. action.Invoke(list);
  1125. }
  1126. });
  1127. item.Events().AddHandler(menuText, handle);
  1128. item.ItemClick += handle;
  1129. item.ImageOptions.SvgImage = meunImage;
  1130. item.Caption = menuText;
  1131. Func<bool> showCondition = () => view.GetSelectedRows().Any();
  1132. item.Tag = showCondition;
  1133. tag.BarM.Items.Add(item);
  1134. popupMenu.AddItem(item);
  1135. popupMenu.Manager = tag.BarM;
  1136. tag.PopupMenu = popupMenu;
  1137. return grid;
  1138. }
  1139. /// <summary>
  1140. /// GridControl添加多行选择元素的右键菜单(自动启用UseMultiSelect)
  1141. /// </summary>
  1142. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1143. /// <param name="grid">GridControl控件</param>
  1144. /// <param name="menuText">菜单标题</param>
  1145. /// <param name="meunImage">菜单图标</param>
  1146. /// <param name="action">菜单要执行的异步事件函数,参数为选中的一行或多行元素</param>
  1147. /// <returns></returns>
  1148. public static GridControl AddMultRowMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1149. Func<List<T>, Task> action)
  1150. {
  1151. grid.UseMultiSelect();
  1152. GridTag tag = grid.Tag as GridTag;
  1153. var view = grid.MainView as GridView;
  1154. if (tag.BarM == null)
  1155. {
  1156. tag.BarM = new BarManager();
  1157. tag.BarM.Form = grid;
  1158. }
  1159. if (tag.PopupMenu == null)
  1160. {
  1161. tag.PopupMenu = new PopupMenu();
  1162. }
  1163. var popupMenu = tag.PopupMenu;
  1164. BarButtonItem item = new BarButtonItem();
  1165. var handle = new ItemClickEventHandler(async (sender, e) =>
  1166. {
  1167. if (action != null)
  1168. {
  1169. var rows = view.GetSelectedRows();
  1170. List<T> list = new List<T>();
  1171. foreach (var row in rows)
  1172. {
  1173. if (row < 0) continue;
  1174. list.Add((T)view.GetRow(row));
  1175. }
  1176. if (list.Any())
  1177. await action.Invoke(list);
  1178. }
  1179. });
  1180. item.Events().AddHandler(menuText, handle);
  1181. item.ItemClick += handle;
  1182. item.ImageOptions.SvgImage = meunImage;
  1183. item.Caption = menuText;
  1184. Func<bool> showCondition = () => view.GetSelectedRows().Any();
  1185. item.Tag = showCondition;
  1186. tag.BarM.Items.Add(item);
  1187. popupMenu.AddItem(item);
  1188. popupMenu.Manager = tag.BarM;
  1189. tag.PopupMenu = popupMenu;
  1190. return grid;
  1191. }
  1192. /// <summary>
  1193. /// GridControl添加内容区的右键菜单
  1194. /// </summary>
  1195. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1196. /// <param name="grid">GridControl控件</param>
  1197. /// <param name="menuText">菜单标题</param>
  1198. /// <param name="meunImage">菜单图标</param>
  1199. /// <param name="action">菜单要执行的事件,参数为绑定的数据源</param>
  1200. /// <param name="showWithNoneDataRow">内容区没有元素时是否显示此菜单,默认显示</param>
  1201. /// <returns></returns>
  1202. public static GridControl AddContentMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1203. Action<List<T>> action, bool showWithNoneDataRow = true)
  1204. {
  1205. GridTag tag = grid.Tag as GridTag;
  1206. var view = grid.MainView as GridView;
  1207. if (tag.BarM == null)
  1208. {
  1209. tag.BarM = new BarManager();
  1210. tag.BarM.Form = grid;
  1211. }
  1212. if (tag.PopupMenu == null)
  1213. {
  1214. tag.PopupMenu = new PopupMenu();
  1215. }
  1216. var popupMenu = tag.PopupMenu;
  1217. BarButtonItem item = new BarButtonItem();
  1218. var handle = new ItemClickEventHandler((sender, e) =>
  1219. {
  1220. if (action != null)
  1221. {
  1222. if (grid.DataSource is List<T> ds)
  1223. {
  1224. if (!showWithNoneDataRow && (ds == null || ds.Count == 0)) return;
  1225. item.Enabled = false;
  1226. action.Invoke(ds);
  1227. }
  1228. else if (grid.DataSource is BindingList<T> bl)
  1229. {
  1230. if (!showWithNoneDataRow && (bl == null || bl.Count == 0)) return;
  1231. item.Enabled = false;
  1232. action.Invoke(bl.ToList());
  1233. }
  1234. item.Enabled = true;
  1235. }
  1236. });
  1237. item.Events().AddHandler(menuText, handle);
  1238. item.ItemClick += handle;
  1239. item.ImageOptions.SvgImage = meunImage;
  1240. item.Caption = menuText;
  1241. tag.BarM.Items.Add(item);
  1242. popupMenu.AddItem(item);
  1243. popupMenu.Manager = tag.BarM;
  1244. tag.PopupMenu = popupMenu;
  1245. return grid;
  1246. }
  1247. /// <summary>
  1248. /// GridControl添加内容区的右键菜单
  1249. /// </summary>
  1250. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1251. /// <param name="grid">GridControl控件</param>
  1252. /// <param name="menuText">菜单标题</param>
  1253. /// <param name="meunImage">菜单图标</param>
  1254. /// <param name="action">菜单要执行的事件,参数为绑定的数据源</param>
  1255. /// <param name="showWithNoneDataRow">内容区没有元素时是否显示此菜单,默认显示</param>
  1256. /// <returns></returns>
  1257. public static GridControl AddContentMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1258. Func<List<T>, Task> action, bool showWithNoneDataRow = true)
  1259. {
  1260. GridTag tag = grid.Tag as GridTag;
  1261. var view = grid.MainView as GridView;
  1262. if (tag.BarM == null)
  1263. {
  1264. tag.BarM = new BarManager();
  1265. tag.BarM.Form = grid;
  1266. }
  1267. if (tag.PopupMenu == null)
  1268. {
  1269. tag.PopupMenu = new PopupMenu();
  1270. }
  1271. var popupMenu = tag.PopupMenu;
  1272. BarButtonItem item = new BarButtonItem();
  1273. var handle = new ItemClickEventHandler(async (sender, e) =>
  1274. {
  1275. if (action != null)
  1276. {
  1277. if (grid.DataSource is List<T> ds)
  1278. {
  1279. if (!showWithNoneDataRow && (ds == null || ds.Count == 0)) return;
  1280. item.Enabled = false;
  1281. await action.Invoke(ds);
  1282. }
  1283. else if (grid.DataSource is BindingList<T> bl)
  1284. {
  1285. if (!showWithNoneDataRow && (bl == null || bl.Count == 0)) return;
  1286. item.Enabled = false;
  1287. await action.Invoke(bl.ToList());
  1288. }
  1289. item.Enabled = true;
  1290. }
  1291. });
  1292. item.Events().AddHandler(menuText, handle);
  1293. item.ItemClick += handle;
  1294. item.ImageOptions.SvgImage = meunImage;
  1295. item.Caption = menuText;
  1296. tag.BarM.Items.Add(item);
  1297. popupMenu.AddItem(item);
  1298. popupMenu.Manager = tag.BarM;
  1299. tag.PopupMenu = popupMenu;
  1300. return grid;
  1301. }
  1302. private static void View_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e)
  1303. {
  1304. if (e.Menu != null)
  1305. {
  1306. foreach (DXMenuItem item in e.Menu.Items)
  1307. {
  1308. if (!item.Enabled)
  1309. {
  1310. item.Visible = false;
  1311. continue;
  1312. }
  1313. }
  1314. }
  1315. //if (e.HitInfo.HitTest == DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitTest.EmptyRow)
  1316. //{
  1317. // return;
  1318. //}
  1319. var view = sender as GridView;
  1320. var grid = view.GridControl;
  1321. var p = grid.PointToScreen(e.Point);
  1322. var tag = grid.Tag as GridTag;
  1323. if (tag?.PopupMenu != null)
  1324. {
  1325. foreach (BarButtonItemLink item in tag?.PopupMenu?.ItemLinks)
  1326. {
  1327. var buttonItem = item.Item;
  1328. if (buttonItem.Tag != null && buttonItem.Tag is Func<bool> showCondition)
  1329. {
  1330. if (showCondition())
  1331. buttonItem.Visibility = BarItemVisibility.Always;
  1332. else
  1333. buttonItem.Visibility = BarItemVisibility.Never;
  1334. }
  1335. }
  1336. tag?.PopupMenu?.ShowPopup(p);
  1337. }
  1338. }
  1339. public static GridControl DrawGridColumnHeaderCheckBox(this GridControl grid)
  1340. {
  1341. //View的 Editable要为true
  1342. var view = grid.MainView as GridView;
  1343. view.OptionsBehavior.Editable = true;
  1344. view.OptionsSelection.MultiSelect = true;
  1345. view.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CheckBoxRowSelect;
  1346. foreach (GridColumn item in view.Columns)
  1347. {
  1348. item.OptionsColumn.AllowEdit = false;
  1349. }
  1350. return grid;
  1351. }
  1352. }