GridControlEx.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. using DevExpress.Utils;
  2. using DevExpress.Utils.Menu;
  3. using DevExpress.Utils.Svg;
  4. using DevExpress.XtraBars;
  5. using DevExpress.XtraEditors;
  6. using DevExpress.XtraEditors.Controls;
  7. using DevExpress.XtraGrid;
  8. using DevExpress.XtraGrid.Columns;
  9. using DevExpress.XtraGrid.Views.Grid;
  10. using DxHelper;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Drawing;
  14. using System.IO;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. using System.Windows.Forms;
  19. using static System.Windows.Forms.VisualStyles.VisualStyleElement.ListView;
  20. public static class GridControlEx
  21. {
  22. class GridTag
  23. {
  24. public GridTag() { }
  25. public PopupMenu PopupMenu { get; set; }
  26. public BarManager BarM { get; set; }
  27. }
  28. /// <summary>
  29. /// 初始化表格(默认禁用分组)
  30. /// </summary>
  31. /// <param name="grid"></param>
  32. /// <param name="dataSource">绑定的数据源</param>
  33. /// <param name="rowHeight">行高(默认24px)</param>
  34. /// <param name="showScrollH">是否显示水平滚动条(默认不显示)</param>
  35. /// <typeparam name="T">绑定的数据源模型类型</typeparam>
  36. /// <returns></returns>
  37. public static GridControl UseDefault<T>(this GridControl grid,List<T> dataSource, int rowHeight = 24, bool showScrollH = false)
  38. {
  39. grid.DataSource = dataSource;
  40. grid.MainView.BorderStyle = BorderStyles.Flat;
  41. var view = grid.MainView as GridView;
  42. view.CustomColumnDisplayText += View_CustomColumnDisplayText;
  43. view.Appearance.HeaderPanel.TextOptions.HAlignment = HorzAlignment.Center;
  44. view.Appearance.Row.Options.UseTextOptions = true;
  45. view.Appearance.Row.TextOptions.HAlignment = HorzAlignment.Center;
  46. view.OptionsView.ColumnHeaderAutoHeight = DefaultBoolean.True;
  47. view.RowHeight = rowHeight;
  48. view.OptionsView.ShowGroupPanel = false;
  49. view.OptionsBehavior.Editable = false;
  50. view.OptionsView.ShowDetailButtons = false;
  51. view.OptionsView.ShowIndicator = false;
  52. view.OptionsMenu.EnableColumnMenu = true;
  53. view.OptionsCustomization.AllowFilter = true;
  54. view.OptionsCustomization.AllowGroup = false;
  55. view.OptionsCustomization.AllowSort = true;
  56. view.OptionsCustomization.AllowColumnMoving = true;
  57. view.OptionsCustomization.AllowMergedGrouping = DefaultBoolean.False;
  58. view.OptionsSelection.MultiSelect = false;
  59. view.OptionsCustomization.AllowRowSizing = false;
  60. view.OptionsCustomization.AllowQuickHideColumns = false;
  61. view.OptionsMenu.EnableGroupPanelMenu = false;
  62. view.OptionsMenu.EnableGroupRowMenu = false;
  63. view.OptionsMenu.EnableFooterMenu = false;
  64. view.OptionsLayout.StoreAllOptions = true;
  65. view.OptionsLayout.StoreAppearance = true;
  66. view.OptionsLayout.StoreDataSettings = true;
  67. view.OptionsLayout.StoreVisualOptions = true;
  68. view.OptionsLayout.StoreFormatRules = true;
  69. view.OptionsView.ColumnAutoWidth = !showScrollH;
  70. view.PopupMenuShowing += View_PopupMenuShowing;
  71. view.OptionsSelection.EnableAppearanceFocusedCell = false;
  72. string GetLayoutName()
  73. {
  74. Control ctrl;
  75. if (view.Tag is SearchLookUpEdit searchLookUpEdit)
  76. ctrl = searchLookUpEdit;
  77. else
  78. ctrl = grid;
  79. while (ctrl.Parent != null)
  80. {
  81. ctrl = ctrl.Parent;
  82. if (ctrl is UserControl) break;
  83. }
  84. var props = typeof(T).GetProperties();
  85. StringBuilder sb = new StringBuilder();
  86. foreach (var item in props)
  87. {
  88. sb.Append(item.Name);
  89. }
  90. var md5 = MD5Helper.StrToMD5(sb.ToString());
  91. if (view.Tag is SearchLookUpEdit searchLookUpEdit2)
  92. return $"{ctrl.Name}_{searchLookUpEdit2.Name}_{md5}";
  93. else
  94. return $"{ctrl.Name}_{grid.Name}_{md5}";
  95. }
  96. string name = GetLayoutName();
  97. void SaveLayoutAction()
  98. {
  99. Form frm = null;
  100. if (view.Tag is SearchLookUpEdit edit)
  101. frm = edit.FindForm();
  102. else
  103. frm = grid.FindForm();
  104. if (frm != null)
  105. {
  106. frm.VisibleChanged += (sender2, e2) =>
  107. {
  108. Directory.CreateDirectory("Layout");
  109. if (name == null) return;
  110. grid.MainView?.SaveLayoutToXml($"Layout\\{name}.xml", OptionsLayoutBase.FullLayout);
  111. };
  112. }
  113. }
  114. if (grid.IsLoaded)
  115. {
  116. SaveLayoutAction();
  117. }
  118. else
  119. {
  120. grid.Load += (sender, e) => SaveLayoutAction();
  121. }
  122. if (name != null && File.Exists($"Layout\\{name}.xml"))
  123. {
  124. view.RestoreLayoutFromXml($"Layout\\{name}.xml", OptionsLayoutBase.FullLayout);
  125. }
  126. view.KeyUp += View_KeyUp;
  127. grid.Tag = new GridTag();
  128. return grid;
  129. }
  130. /// <summary>
  131. /// 为GirdControl启用右键新增数据的功能
  132. /// </summary>
  133. /// <typeparam name="T"></typeparam>
  134. /// <param name="grid"></param>
  135. /// <param name="menuCaption"></param>
  136. /// <param name="callback">一个回调函数,返回新增的数据</param>
  137. /// <returns></returns>
  138. public static GridControl UseAdd<T>(this GridControl grid, Func<T> callback, string menuCaption = "新增")
  139. {
  140. var view = grid.MainView as GridView;
  141. view.CustomDrawEmptyForeground += (sender, e) =>
  142. {
  143. string emptyText = "右键添加";
  144. var s = e.Appearance.CalcTextSize(e.Cache, emptyText, e.Bounds.Width).ToSize();
  145. var x = (e.Bounds.Width - s.Width) / 2;
  146. var y = (e.Bounds.Height - s.Height) / 2;
  147. e.Appearance.ForeColor = Color.Gray;
  148. e.Appearance.DrawString(e.Cache, emptyText, new Rectangle(x, y, s.Width, s.Height));
  149. };
  150. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateAdd(), data =>
  151. {
  152. if (callback != null)
  153. {
  154. var addRow = callback();
  155. if (addRow == null) return;
  156. var ds = grid.DataSource as List<T>;
  157. ds.Add(addRow);
  158. view.RefreshData();
  159. }
  160. }, true);
  161. return grid;
  162. }
  163. /// <summary>
  164. /// 为GirdControl启用右键新增数据的功能
  165. /// </summary>
  166. /// <typeparam name="T"></typeparam>
  167. /// <param name="grid"></param>
  168. /// <param name="menuCaption"></param>
  169. /// <param name="callback">一个回调函数,返回新增的数据</param>
  170. /// <returns></returns>
  171. public static GridControl UseAddAsync<T>(this GridControl grid, Func<Task<T>> callback, string menuCaption = "新增")
  172. {
  173. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateAdd(), async data =>
  174. {
  175. if (callback != null)
  176. {
  177. var addRow = await callback();
  178. if (addRow == null) return;
  179. var view = grid.MainView as GridView;
  180. var ds = grid.DataSource as List<T>;
  181. ds.Add(addRow);
  182. view.RefreshData();
  183. }
  184. }, true);
  185. return grid;
  186. }
  187. /// <summary>
  188. /// 为GridControl启用右编辑选中的单行功能
  189. /// </summary>
  190. /// <typeparam name="T"></typeparam>
  191. /// <param name="grid"></param>
  192. /// <param name="menuCaption"></param>
  193. /// <param name="callback"></param>
  194. /// <returns></returns>
  195. public static GridControl UseEdit<T>(this GridControl grid, Func<T, T> callback, string menuCaption = "编辑")
  196. {
  197. grid.AddRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateEdit(), data =>
  198. {
  199. if (callback != null)
  200. {
  201. var newRow = callback(data);
  202. if (newRow == null) return;
  203. var view = grid.MainView as GridView;
  204. var ds = grid.DataSource as List<T>;
  205. var idx = ds.IndexOf(data);
  206. ds.Remove(data);
  207. ds.Insert(idx, newRow);
  208. view.RefreshData();
  209. }
  210. }, null);
  211. return grid;
  212. }
  213. /// <summary>
  214. /// 为GridControl启用右编辑选中的单行功能
  215. /// </summary>
  216. /// <typeparam name="T"></typeparam>
  217. /// <param name="grid"></param>
  218. /// <param name="menuCaption"></param>
  219. /// <param name="callback"></param>
  220. /// <returns></returns>
  221. public static GridControl UseEditAsync<T>(this GridControl grid, Func<T, Task<T>> callback, string menuCaption = "编辑")
  222. {
  223. grid.AddRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateEdit(), async data =>
  224. {
  225. if (callback != null)
  226. {
  227. var newRow = await callback(data);
  228. if (newRow == null) return;
  229. var view = grid.MainView as GridView;
  230. var ds = grid.DataSource as List<T>;
  231. var idx = ds.IndexOf(data);
  232. ds.Remove(data);
  233. ds.Insert(idx, newRow);
  234. view.RefreshData();
  235. }
  236. }, null);
  237. return grid;
  238. }
  239. /// <summary>
  240. /// 为GridControl启用右删除选中的一行或多行功能(自动启用UseMultiSelect)
  241. /// </summary>
  242. /// <typeparam name="T"></typeparam>
  243. /// <param name="grid"></param>
  244. /// <param name="menuCaption"></param>
  245. /// <param name="action"></param>
  246. /// <returns></returns>
  247. public static GridControl UseDelete<T>(this GridControl grid, Func<List<T>, bool> action = null, string menuCaption = "删除")
  248. {
  249. grid.AddMultRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClose(), data =>
  250. {
  251. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认删除选中的记录?共[{data.Count}]条")) return;
  252. if (action != null)
  253. {
  254. bool succeed = action(data);
  255. if (!succeed) return;
  256. }
  257. var view = grid.MainView as GridView;
  258. view.DeleteSelectedRows();
  259. view.RefreshData();
  260. });
  261. return grid;
  262. }
  263. /// <summary>
  264. /// 为GridControl启用右删除选中的一行或多行功能(自动启用UseMultiSelect)
  265. /// </summary>
  266. /// <typeparam name="T"></typeparam>
  267. /// <param name="grid"></param>
  268. /// <param name="menuCaption"></param>
  269. /// <param name="action"></param>
  270. /// <returns></returns>
  271. public static GridControl UseDeleteAsync<T>(this GridControl grid, Func<List<T>, Task<bool>> action = null, string menuCaption = "删除")
  272. {
  273. grid.AddMultRowMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClose(), async data =>
  274. {
  275. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认删除选中的记录?共[{data.Count()}]条")) return;
  276. if (action != null)
  277. {
  278. bool succeed = await action(data);
  279. if (!succeed) return;
  280. }
  281. var view = grid.MainView as GridView;
  282. view.DeleteSelectedRows();
  283. view.RefreshData();
  284. });
  285. return grid;
  286. }
  287. /// <summary>
  288. /// 为GirdControl启用右键清除所有数据的功能(action执行完成后会自动清空表格中对应的数据)
  289. /// </summary>
  290. /// <typeparam name="T"></typeparam>
  291. /// <param name="grid"></param>
  292. /// <param name="menuCaption"></param>
  293. /// <param name="action"></param>
  294. /// <param name="existMenu"></param>
  295. /// <returns></returns>
  296. public static GridControl UseClear<T>(this GridControl grid, Func<List<T>, bool> action = null, string menuCaption = "清除")
  297. {
  298. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClear(), data =>
  299. {
  300. if (data == null || data.Count == 0) return;
  301. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认清空所有记录?共[{data.Count}]条")) return;
  302. if (action != null)
  303. {
  304. bool succeed = action(data);
  305. if (!succeed) return;
  306. }
  307. var view = grid.MainView as GridView;
  308. data.Clear();
  309. view.RefreshData();
  310. }, false);
  311. return grid;
  312. }
  313. /// <summary>
  314. /// 为GirdControl启用右键清除所有数据的功能(action执行完成后会自动清空表格中对应的数据)
  315. /// </summary>
  316. /// <typeparam name="T"></typeparam>
  317. /// <param name="grid"></param>
  318. /// <param name="menuCaption"></param>
  319. /// <param name="action"></param>
  320. /// <param name="existMenu"></param>
  321. /// <returns></returns>
  322. public static GridControl UseClearAsync<T>(this GridControl grid, Func<List<T>, Task<bool>> action = null, string menuCaption = "清除")
  323. {
  324. grid.AddContentMenu<T>(menuCaption, DxHelper.SvgHelper.CreateClear(), async data =>
  325. {
  326. if (data == null || data.Count == 0) return;
  327. if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认清空所有记录?共[{data.Count}]条")) return;
  328. if (action != null)
  329. {
  330. bool succeed = await action(data);
  331. if (!succeed) return;
  332. }
  333. var view = grid.MainView as GridView;
  334. data.Clear();
  335. view.RefreshData();
  336. }, false);
  337. return grid;
  338. }
  339. public static GridControl UseExportCsv(this GridControl grid)
  340. {
  341. GridTag tag = grid.Tag as GridTag;
  342. if (tag.BarM == null)
  343. {
  344. tag.BarM = new BarManager();
  345. tag.BarM.Form = grid;
  346. }
  347. if (tag.PopupMenu == null)
  348. {
  349. tag.PopupMenu = new PopupMenu();
  350. }
  351. PopupMenu popupMenu = tag.PopupMenu;
  352. BarButtonItem item = new BarButtonItem();
  353. item.ItemClick += (sender, e) =>
  354. {
  355. SaveFileDialog dialog = new SaveFileDialog();
  356. dialog.Filter = "csv|*.csv";
  357. if (dialog.ShowDialog() == DialogResult.OK)
  358. {
  359. var view = grid.MainView as GridView;
  360. view.ExportToCsv(dialog.FileName);
  361. }
  362. };
  363. item.ImageOptions.SvgImage = DxHelper.SvgHelper.CreateExportCsv();
  364. item.Caption = "导出(CSV)";
  365. tag.BarM.Items.Add(item);
  366. popupMenu.AddItem(item);
  367. popupMenu.Manager = tag.BarM;
  368. tag.PopupMenu = popupMenu;
  369. return grid;
  370. }
  371. public static GridControl UseExportXlsx(this GridControl grid)
  372. {
  373. GridTag tag = grid.Tag as GridTag;
  374. if (tag.BarM == null)
  375. {
  376. tag.BarM = new BarManager();
  377. tag.BarM.Form = grid;
  378. }
  379. if (tag.PopupMenu == null)
  380. {
  381. tag.PopupMenu = new PopupMenu();
  382. }
  383. PopupMenu popupMenu = tag.PopupMenu;
  384. BarButtonItem item = new BarButtonItem();
  385. item.ItemClick += (sender, e) =>
  386. {
  387. SaveFileDialog dialog = new SaveFileDialog();
  388. dialog.Filter = "Excel文件|*.xlsx";
  389. if (dialog.ShowDialog() == DialogResult.OK)
  390. {
  391. var view = grid.MainView as GridView;
  392. view.ExportToXlsx(dialog.FileName);
  393. }
  394. };
  395. item.ImageOptions.SvgImage = DxHelper.SvgHelper.CreateExportXlsx();
  396. item.Caption = "导出(Excel)";
  397. tag.BarM.Items.Add(item);
  398. popupMenu.AddItem(item);
  399. popupMenu.Manager = tag.BarM;
  400. tag.PopupMenu = popupMenu;
  401. return grid;
  402. }
  403. private static void View_KeyUp(object sender, KeyEventArgs e)
  404. {
  405. if (e.Control && e.Shift & e.KeyCode == Keys.C)
  406. {
  407. var view = sender as GridView;
  408. if (view.FocusedColumn == null) return;
  409. var val = view.GetFocusedRowCellDisplayText(view.FocusedColumn);
  410. if (string.IsNullOrWhiteSpace(val)) return;
  411. Clipboard.SetText(val);
  412. }
  413. }
  414. private static void View_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e)
  415. {
  416. if (e.Column.ColumnType == typeof(DateTime) || e.Column.ColumnType == typeof(DateTime?))
  417. {
  418. if (e.Value == null) return;
  419. if (e.Column.FieldName == "SigTime")
  420. e.DisplayText = Convert.ToDateTime(e.Value).ToString("yyyy-MM-dd HH:mm:ss.fff");
  421. else
  422. e.DisplayText = Convert.ToDateTime(e.Value).ToString("yyyy-MM-dd HH:mm:ss");
  423. }
  424. }
  425. public static GridControl ShowColumn(this GridControl grid, params string[] colField)
  426. {
  427. var view = grid.MainView as GridView;
  428. if (view.Columns.Count == 0) return grid;
  429. if (colField == null || colField.Length == 0) return grid;
  430. foreach (GridColumn item in view.Columns)
  431. {
  432. if (colField.Contains(item.FieldName))
  433. item.Visible = true;
  434. }
  435. return grid;
  436. }
  437. public static GridControl UseMultiSelect(this GridControl grid)
  438. {
  439. var view = grid.MainView as GridView;
  440. view.OptionsSelection.MultiSelect = true;
  441. view.OptionsSelection.MultiSelectMode = GridMultiSelectMode.RowSelect;
  442. return grid;
  443. }
  444. public static GridControl UseGroup(this GridControl grid)
  445. {
  446. var view = grid.MainView as GridView;
  447. view.OptionsView.GroupFooterShowMode = GroupFooterShowMode.Hidden;
  448. view.OptionsView.ShowGroupPanel = true;
  449. view.OptionsCustomization.AllowGroup = true;
  450. view.OptionsCustomization.AllowSort = true;
  451. return grid;
  452. }
  453. public static GridControl UseFooter(this GridControl grid, Action<object, DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgs> act)
  454. {
  455. var view = grid.MainView as GridView;
  456. view.OptionsView.ShowFooter = true;
  457. view.CustomDrawFooter += (s, e) => act(s, e);
  458. return grid;
  459. }
  460. public static GridControl UseEdit(this GridControl grid)
  461. {
  462. var view = grid.MainView as GridView;
  463. view.OptionsBehavior.Editable = true;
  464. view.OptionsSelection.EnableAppearanceFocusedCell = true;
  465. foreach (GridColumn item in view.Columns)
  466. {
  467. item.OptionsColumn.AllowEdit = false;
  468. }
  469. return grid;
  470. }
  471. public static GridControl UseRowNumber(this GridControl grid)
  472. {
  473. var view = grid.MainView as GridView;
  474. view.OptionsView.ShowIndicator = true;
  475. view.CustomDrawRowIndicator += (s, e) =>
  476. {
  477. if (!e.Info.IsRowIndicator) return;
  478. if (e.RowHandle < 0) return;
  479. e.Handled = true;
  480. string txt = (e.RowHandle + 1).ToString();
  481. var txtSize = e.Graphics.MeasureString(txt, e.Appearance.Font);
  482. if (view.IndicatorWidth < txtSize.Width + 20)
  483. {
  484. view.IndicatorWidth++;
  485. }
  486. var loc = new PointF(e.Bounds.X + e.Bounds.Width / 2f - txtSize.Width / 2f + 2,
  487. e.Bounds.Y + e.Bounds.Height / 2f - txtSize.Height / 2f);
  488. e.Cache.FillRectangle(new SolidBrush(e.Appearance.BackColor), e.Bounds);
  489. e.Cache.DrawString(txt, e.Appearance.Font, new SolidBrush(e.Appearance.ForeColor), loc);
  490. };
  491. view.RowCountChanged += (sender, e) =>
  492. {
  493. if (view.RowCount == 0)
  494. view.IndicatorWidth = -1;
  495. else
  496. view.IndicatorWidth = view.RowCount.ToString().Length * 6 + 20;
  497. };
  498. return grid;
  499. }
  500. public static GridControl HideColumn(this GridControl grid, params string[] colField)
  501. {
  502. var view = grid.MainView as GridView;
  503. if (colField == null || colField.Length == 0) return grid;
  504. foreach (GridColumn item in view.Columns)
  505. {
  506. if (colField.Contains(item.FieldName))
  507. item.Visible = false;
  508. }
  509. return grid;
  510. }
  511. /// <summary>
  512. /// GridControl添加单行元素选择后的右键菜单(没有选中的数据或showCondition返回false时不会显示此菜单按钮)
  513. /// </summary>
  514. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  515. /// <param name="grid">GridControl控件</param>
  516. /// <param name="menuText">菜单标题</param>
  517. /// <param name="meunImage">菜单图标</param>
  518. /// <param name="action">菜单要执行的事件,参数为选中的单行元素</param>
  519. /// <param name="showCondition">菜单显示的条件</param>
  520. /// <returns></returns>
  521. public static GridControl AddRowMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  522. Action<T> action, Func<T, bool> showCondition = null)
  523. {
  524. GridTag tag = grid.Tag as GridTag;
  525. var view = grid.MainView as GridView;
  526. if (tag.BarM == null)
  527. {
  528. tag.BarM = new BarManager();
  529. tag.BarM.Form = grid;
  530. }
  531. if (tag.PopupMenu == null)
  532. {
  533. tag.PopupMenu = new PopupMenu();
  534. }
  535. var popupMenu = tag.PopupMenu;
  536. BarButtonItem item = new BarButtonItem();
  537. Func<bool> showConditionAll = () =>
  538. {
  539. if (!view.GetSelectedRows().Any()) return false;
  540. if (showCondition == null)
  541. return true;
  542. else
  543. return showCondition((T)view.GetFocusedRow());
  544. };
  545. item.Tag = showConditionAll;
  546. item.ItemClick += (sender, e) =>
  547. {
  548. if (action != null)
  549. {
  550. if (view.GetFocusedRow() == null) return;
  551. item.Enabled = false;
  552. action.Invoke((T)view.GetFocusedRow());
  553. item.Enabled = true;
  554. }
  555. };
  556. item.ImageOptions.SvgImage = meunImage;
  557. item.Caption = menuText;
  558. tag.BarM.Items.Add(item);
  559. popupMenu.AddItem(item);
  560. popupMenu.Manager = tag.BarM;
  561. tag.PopupMenu = popupMenu;
  562. return grid;
  563. }
  564. /// <summary>
  565. /// GridControl添加多行选择元素的右键菜单(没有选中的数据时不会显示此菜单按钮)
  566. /// </summary>
  567. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  568. /// <param name="grid">GridControl控件</param>
  569. /// <param name="menuText">菜单标题</param>
  570. /// <param name="meunImage">菜单图标</param>
  571. /// <param name="action">菜单要执行的事件,参数为选中的一行或多行元素</param>
  572. /// <returns></returns>
  573. public static GridControl AddMultRowMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  574. Action<List<T>> action)
  575. {
  576. grid.UseMultiSelect();
  577. GridTag tag = grid.Tag as GridTag;
  578. var view = grid.MainView as GridView;
  579. if (tag.BarM == null)
  580. {
  581. tag.BarM = new BarManager();
  582. tag.BarM.Form = grid;
  583. }
  584. if (tag.PopupMenu == null)
  585. {
  586. tag.PopupMenu = new PopupMenu();
  587. }
  588. var popupMenu = tag.PopupMenu;
  589. BarButtonItem item = new BarButtonItem();
  590. item.ItemClick += (sender, e) =>
  591. {
  592. if (action != null)
  593. {
  594. var rows = view.GetSelectedRows();
  595. List<T> list = new List<T>();
  596. foreach (var row in rows)
  597. {
  598. if (row < 0) continue;
  599. list.Add((T)view.GetRow(row));
  600. }
  601. if (list.Any())
  602. action.Invoke(list);
  603. }
  604. };
  605. item.ImageOptions.SvgImage = meunImage;
  606. item.Caption = menuText;
  607. Func<bool> showCondition = () => view.GetSelectedRows().Any();
  608. item.Tag = showCondition;
  609. tag.BarM.Items.Add(item);
  610. popupMenu.AddItem(item);
  611. popupMenu.Manager = tag.BarM;
  612. tag.PopupMenu = popupMenu;
  613. return grid;
  614. }
  615. /// <summary>
  616. /// GridControl添加内容区的右键菜单
  617. /// </summary>
  618. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  619. /// <param name="grid">GridControl控件</param>
  620. /// <param name="menuText">菜单标题</param>
  621. /// <param name="meunImage">菜单图标</param>
  622. /// <param name="action">菜单要执行的事件,参数为绑定的数据源</param>
  623. /// <param name="showWithNoneDataRow">内容区没有元素时是否显示此菜单,默认显示</param>
  624. /// <param name="existMenu">如果GirdControl行元素已经存在PopupMenu,则需要传入存在的PopupMenu)</param>
  625. /// <returns></returns>
  626. public static GridControl AddContentMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  627. Action<List<T>> action, bool showWithNoneDataRow = true)
  628. {
  629. GridTag tag = grid.Tag as GridTag;
  630. var view = grid.MainView as GridView;
  631. if (tag.BarM == null)
  632. {
  633. tag.BarM = new BarManager();
  634. tag.BarM.Form = grid;
  635. }
  636. if (tag.PopupMenu == null)
  637. {
  638. tag.PopupMenu = new PopupMenu();
  639. }
  640. var popupMenu = tag.PopupMenu;
  641. BarButtonItem item = new BarButtonItem();
  642. item.ItemClick += (sender, e) =>
  643. {
  644. if (action != null)
  645. {
  646. var ds = grid.DataSource as List<T>;
  647. if (!showWithNoneDataRow && (ds == null || ds.Count == 0)) return;
  648. item.Enabled = false;
  649. action.Invoke(ds);
  650. item.Enabled = true;
  651. }
  652. };
  653. item.ImageOptions.SvgImage = meunImage;
  654. item.Caption = menuText;
  655. tag.BarM.Items.Add(item);
  656. popupMenu.AddItem(item);
  657. popupMenu.Manager = tag.BarM;
  658. tag.PopupMenu = popupMenu;
  659. return grid;
  660. }
  661. private static void View_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e)
  662. {
  663. if (e.Menu != null)
  664. {
  665. foreach (DXMenuItem item in e.Menu.Items)
  666. {
  667. if (!item.Enabled)
  668. {
  669. item.Visible = false;
  670. continue;
  671. }
  672. }
  673. }
  674. //if (e.HitInfo.HitTest == DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitTest.EmptyRow)
  675. //{
  676. // return;
  677. //}
  678. var view = sender as GridView;
  679. var grid = view.GridControl;
  680. var p = grid.PointToScreen(e.Point);
  681. var tag = grid.Tag as GridTag;
  682. if (tag?.PopupMenu != null)
  683. {
  684. foreach (BarButtonItemLink item in tag?.PopupMenu?.ItemLinks)
  685. {
  686. var buttonItem = item.Item;
  687. if (buttonItem.Tag != null && buttonItem.Tag is Func<bool> showCondition)
  688. {
  689. if (showCondition())
  690. buttonItem.Visibility = BarItemVisibility.Always;
  691. else
  692. buttonItem.Visibility = BarItemVisibility.Never;
  693. }
  694. }
  695. tag?.PopupMenu?.ShowPopup(p);
  696. }
  697. }
  698. }