GridControlEx.cs 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407
  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. view.Columns["Id"].VisibleIndex = 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. /// GridControl添加单行元素选择后的右键菜单
  957. /// </summary>
  958. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  959. /// <param name="grid">GridControl控件</param>
  960. /// <param name="menuText">菜单标题</param>
  961. /// <param name="meunImage">菜单图标</param>
  962. /// <param name="action">菜单要执行的事件函数,参数为选中的单行元素</param>
  963. /// <param name="showCondition">菜单显示的条件</param>
  964. /// <returns></returns>
  965. public static GridControl AddRowMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  966. Action<T> action, Func<T, bool> showCondition = null)
  967. {
  968. GridTag tag = grid.Tag as GridTag;
  969. var view = grid.MainView as GridView;
  970. if (tag.BarM == null)
  971. {
  972. tag.BarM = new BarManager();
  973. tag.BarM.Form = grid;
  974. }
  975. if (tag.PopupMenu == null)
  976. {
  977. tag.PopupMenu = new PopupMenu();
  978. }
  979. var popupMenu = tag.PopupMenu;
  980. BarButtonItem item = new BarButtonItem();
  981. tag.RowButtonsItems.Add(item);
  982. Func<bool> showConditionAll = () =>
  983. {
  984. if (!view.GetSelectedRows().Any()) return false;
  985. if (showCondition == null)
  986. return true;
  987. else
  988. return showCondition((T)view.GetFocusedRow());
  989. };
  990. item.Tag = showConditionAll;
  991. var handle = new ItemClickEventHandler((sender, e) =>
  992. {
  993. if (action != null)
  994. {
  995. if (view.GetFocusedRow() == null) return;
  996. item.Enabled = false;
  997. action.Invoke((T)view.GetFocusedRow());
  998. item.Enabled = true;
  999. }
  1000. });
  1001. item.Events().AddHandler(menuText, handle);
  1002. item.ItemClick += handle;
  1003. item.ImageOptions.SvgImage = meunImage;
  1004. item.Caption = menuText;
  1005. tag.BarM.Items.Add(item);
  1006. popupMenu.AddItem(item);
  1007. popupMenu.Manager = tag.BarM;
  1008. tag.PopupMenu = popupMenu;
  1009. return grid;
  1010. }
  1011. /// <summary>
  1012. /// GridControl添加单行元素选择后的右键菜单
  1013. /// </summary>
  1014. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1015. /// <param name="grid">GridControl控件</param>
  1016. /// <param name="menuText">菜单标题</param>
  1017. /// <param name="meunImage">菜单图标</param>
  1018. /// <param name="action">菜单要执行的异步事件函数,参数为选中的单行元素</param>
  1019. /// <param name="showCondition">菜单显示的条件</param>
  1020. /// <returns></returns>
  1021. public static GridControl AddRowMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1022. Func<T, Task> action, Func<T, bool> showCondition = null)
  1023. {
  1024. GridTag tag = grid.Tag as GridTag;
  1025. var view = grid.MainView as GridView;
  1026. if (tag.BarM == null)
  1027. {
  1028. tag.BarM = new BarManager();
  1029. tag.BarM.Form = grid;
  1030. }
  1031. if (tag.PopupMenu == null)
  1032. {
  1033. tag.PopupMenu = new PopupMenu();
  1034. }
  1035. var popupMenu = tag.PopupMenu;
  1036. BarButtonItem item = new BarButtonItem();
  1037. tag.RowButtonsItems.Add(item);
  1038. Func<bool> showConditionAll = () =>
  1039. {
  1040. if (!view.GetSelectedRows().Any()) return false;
  1041. if (showCondition == null)
  1042. return true;
  1043. else
  1044. return showCondition((T)view.GetFocusedRow());
  1045. };
  1046. item.Tag = showConditionAll;
  1047. var handle = new ItemClickEventHandler(async (sender, e) =>
  1048. {
  1049. if (action != null)
  1050. {
  1051. if (view.GetFocusedRow() == null) return;
  1052. item.Enabled = false;
  1053. await action.Invoke((T)view.GetFocusedRow());
  1054. item.Enabled = true;
  1055. }
  1056. });
  1057. item.Events().AddHandler(menuText, handle);
  1058. item.ItemClick += handle;
  1059. item.ImageOptions.SvgImage = meunImage;
  1060. item.Caption = menuText;
  1061. tag.BarM.Items.Add(item);
  1062. popupMenu.AddItem(item);
  1063. popupMenu.Manager = tag.BarM;
  1064. tag.PopupMenu = popupMenu;
  1065. return grid;
  1066. }
  1067. /// <summary>
  1068. /// GridControl添加多行选择元素的右键菜单(自动启用UseMultiSelect)
  1069. /// </summary>
  1070. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1071. /// <param name="grid">GridControl控件</param>
  1072. /// <param name="menuText">菜单标题</param>
  1073. /// <param name="meunImage">菜单图标</param>
  1074. /// <param name="action">菜单要执行的事件,参数为选中的一行或多行元素</param>
  1075. /// <returns></returns>
  1076. public static GridControl AddMultRowMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1077. Action<List<T>> action)
  1078. {
  1079. grid.UseMultiSelect();
  1080. GridTag tag = grid.Tag as GridTag;
  1081. var view = grid.MainView as GridView;
  1082. if (tag.BarM == null)
  1083. {
  1084. tag.BarM = new BarManager();
  1085. tag.BarM.Form = grid;
  1086. }
  1087. if (tag.PopupMenu == null)
  1088. {
  1089. tag.PopupMenu = new PopupMenu();
  1090. }
  1091. var popupMenu = tag.PopupMenu;
  1092. BarButtonItem item = new BarButtonItem();
  1093. var handle = new ItemClickEventHandler((sender, e) =>
  1094. {
  1095. if (action != null)
  1096. {
  1097. var rows = view.GetSelectedRows();
  1098. List<T> list = new List<T>();
  1099. foreach (var row in rows)
  1100. {
  1101. if (row < 0) continue;
  1102. list.Add((T)view.GetRow(row));
  1103. }
  1104. if (list.Any())
  1105. action.Invoke(list);
  1106. }
  1107. });
  1108. item.Events().AddHandler(menuText, handle);
  1109. item.ItemClick += handle;
  1110. item.ImageOptions.SvgImage = meunImage;
  1111. item.Caption = menuText;
  1112. Func<bool> showCondition = () => view.GetSelectedRows().Any();
  1113. item.Tag = showCondition;
  1114. tag.BarM.Items.Add(item);
  1115. popupMenu.AddItem(item);
  1116. popupMenu.Manager = tag.BarM;
  1117. tag.PopupMenu = popupMenu;
  1118. return grid;
  1119. }
  1120. /// <summary>
  1121. /// GridControl添加多行选择元素的右键菜单(自动启用UseMultiSelect)
  1122. /// </summary>
  1123. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1124. /// <param name="grid">GridControl控件</param>
  1125. /// <param name="menuText">菜单标题</param>
  1126. /// <param name="meunImage">菜单图标</param>
  1127. /// <param name="action">菜单要执行的异步事件函数,参数为选中的一行或多行元素</param>
  1128. /// <returns></returns>
  1129. public static GridControl AddMultRowMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1130. Func<List<T>, Task> action)
  1131. {
  1132. grid.UseMultiSelect();
  1133. GridTag tag = grid.Tag as GridTag;
  1134. var view = grid.MainView as GridView;
  1135. if (tag.BarM == null)
  1136. {
  1137. tag.BarM = new BarManager();
  1138. tag.BarM.Form = grid;
  1139. }
  1140. if (tag.PopupMenu == null)
  1141. {
  1142. tag.PopupMenu = new PopupMenu();
  1143. }
  1144. var popupMenu = tag.PopupMenu;
  1145. BarButtonItem item = new BarButtonItem();
  1146. var handle = new ItemClickEventHandler(async (sender, e) =>
  1147. {
  1148. if (action != null)
  1149. {
  1150. var rows = view.GetSelectedRows();
  1151. List<T> list = new List<T>();
  1152. foreach (var row in rows)
  1153. {
  1154. if (row < 0) continue;
  1155. list.Add((T)view.GetRow(row));
  1156. }
  1157. if (list.Any())
  1158. await action.Invoke(list);
  1159. }
  1160. });
  1161. item.Events().AddHandler(menuText, handle);
  1162. item.ItemClick += handle;
  1163. item.ImageOptions.SvgImage = meunImage;
  1164. item.Caption = menuText;
  1165. Func<bool> showCondition = () => view.GetSelectedRows().Any();
  1166. item.Tag = showCondition;
  1167. tag.BarM.Items.Add(item);
  1168. popupMenu.AddItem(item);
  1169. popupMenu.Manager = tag.BarM;
  1170. tag.PopupMenu = popupMenu;
  1171. return grid;
  1172. }
  1173. /// <summary>
  1174. /// GridControl添加内容区的右键菜单
  1175. /// </summary>
  1176. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1177. /// <param name="grid">GridControl控件</param>
  1178. /// <param name="menuText">菜单标题</param>
  1179. /// <param name="meunImage">菜单图标</param>
  1180. /// <param name="action">菜单要执行的事件,参数为绑定的数据源</param>
  1181. /// <param name="showWithNoneDataRow">内容区没有元素时是否显示此菜单,默认显示</param>
  1182. /// <returns></returns>
  1183. public static GridControl AddContentMenu<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1184. Action<List<T>> action, bool showWithNoneDataRow = true)
  1185. {
  1186. GridTag tag = grid.Tag as GridTag;
  1187. var view = grid.MainView as GridView;
  1188. if (tag.BarM == null)
  1189. {
  1190. tag.BarM = new BarManager();
  1191. tag.BarM.Form = grid;
  1192. }
  1193. if (tag.PopupMenu == null)
  1194. {
  1195. tag.PopupMenu = new PopupMenu();
  1196. }
  1197. var popupMenu = tag.PopupMenu;
  1198. BarButtonItem item = new BarButtonItem();
  1199. var handle = new ItemClickEventHandler((sender, e) =>
  1200. {
  1201. if (action != null)
  1202. {
  1203. if (grid.DataSource is List<T> ds)
  1204. {
  1205. if (!showWithNoneDataRow && (ds == null || ds.Count == 0)) return;
  1206. item.Enabled = false;
  1207. action.Invoke(ds);
  1208. }
  1209. else if (grid.DataSource is BindingList<T> bl)
  1210. {
  1211. if (!showWithNoneDataRow && (bl == null || bl.Count == 0)) return;
  1212. item.Enabled = false;
  1213. action.Invoke(bl.ToList());
  1214. }
  1215. item.Enabled = true;
  1216. }
  1217. });
  1218. item.Events().AddHandler(menuText, handle);
  1219. item.ItemClick += handle;
  1220. item.ImageOptions.SvgImage = meunImage;
  1221. item.Caption = menuText;
  1222. tag.BarM.Items.Add(item);
  1223. popupMenu.AddItem(item);
  1224. popupMenu.Manager = tag.BarM;
  1225. tag.PopupMenu = popupMenu;
  1226. return grid;
  1227. }
  1228. /// <summary>
  1229. /// GridControl添加内容区的右键菜单
  1230. /// </summary>
  1231. /// <typeparam name="T">GridControl绑定数据源的泛型类型</typeparam>
  1232. /// <param name="grid">GridControl控件</param>
  1233. /// <param name="menuText">菜单标题</param>
  1234. /// <param name="meunImage">菜单图标</param>
  1235. /// <param name="action">菜单要执行的事件,参数为绑定的数据源</param>
  1236. /// <param name="showWithNoneDataRow">内容区没有元素时是否显示此菜单,默认显示</param>
  1237. /// <returns></returns>
  1238. public static GridControl AddContentMenuAsync<T>(this GridControl grid, string menuText, SvgImage meunImage,
  1239. Func<List<T>, Task> action, bool showWithNoneDataRow = true)
  1240. {
  1241. GridTag tag = grid.Tag as GridTag;
  1242. var view = grid.MainView as GridView;
  1243. if (tag.BarM == null)
  1244. {
  1245. tag.BarM = new BarManager();
  1246. tag.BarM.Form = grid;
  1247. }
  1248. if (tag.PopupMenu == null)
  1249. {
  1250. tag.PopupMenu = new PopupMenu();
  1251. }
  1252. var popupMenu = tag.PopupMenu;
  1253. BarButtonItem item = new BarButtonItem();
  1254. var handle = new ItemClickEventHandler(async (sender, e) =>
  1255. {
  1256. if (action != null)
  1257. {
  1258. if (grid.DataSource is List<T> ds)
  1259. {
  1260. if (!showWithNoneDataRow && (ds == null || ds.Count == 0)) return;
  1261. item.Enabled = false;
  1262. await action.Invoke(ds);
  1263. }
  1264. else if (grid.DataSource is BindingList<T> bl)
  1265. {
  1266. if (!showWithNoneDataRow && (bl == null || bl.Count == 0)) return;
  1267. item.Enabled = false;
  1268. await action.Invoke(bl.ToList());
  1269. }
  1270. item.Enabled = true;
  1271. }
  1272. });
  1273. item.Events().AddHandler(menuText, handle);
  1274. item.ItemClick += handle;
  1275. item.ImageOptions.SvgImage = meunImage;
  1276. item.Caption = menuText;
  1277. tag.BarM.Items.Add(item);
  1278. popupMenu.AddItem(item);
  1279. popupMenu.Manager = tag.BarM;
  1280. tag.PopupMenu = popupMenu;
  1281. return grid;
  1282. }
  1283. private static void View_PopupMenuShowing(object sender, PopupMenuShowingEventArgs e)
  1284. {
  1285. if (e.Menu != null)
  1286. {
  1287. foreach (DXMenuItem item in e.Menu.Items)
  1288. {
  1289. if (!item.Enabled)
  1290. {
  1291. item.Visible = false;
  1292. continue;
  1293. }
  1294. }
  1295. }
  1296. //if (e.HitInfo.HitTest == DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitTest.EmptyRow)
  1297. //{
  1298. // return;
  1299. //}
  1300. var view = sender as GridView;
  1301. var grid = view.GridControl;
  1302. var p = grid.PointToScreen(e.Point);
  1303. var tag = grid.Tag as GridTag;
  1304. if (tag?.PopupMenu != null)
  1305. {
  1306. foreach (BarButtonItemLink item in tag?.PopupMenu?.ItemLinks)
  1307. {
  1308. var buttonItem = item.Item;
  1309. if (buttonItem.Tag != null && buttonItem.Tag is Func<bool> showCondition)
  1310. {
  1311. if (showCondition())
  1312. buttonItem.Visibility = BarItemVisibility.Always;
  1313. else
  1314. buttonItem.Visibility = BarItemVisibility.Never;
  1315. }
  1316. }
  1317. tag?.PopupMenu?.ShowPopup(p);
  1318. }
  1319. }
  1320. public static GridControl DrawGridColumnHeaderCheckBox(this GridControl grid)
  1321. {
  1322. //View的 Editable要为true
  1323. var view = grid.MainView as GridView;
  1324. view.OptionsBehavior.Editable = true;
  1325. view.OptionsSelection.MultiSelect = true;
  1326. view.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CheckBoxRowSelect;
  1327. foreach (GridColumn item in view.Columns)
  1328. {
  1329. item.OptionsColumn.AllowEdit = false;
  1330. }
  1331. return grid;
  1332. }
  1333. }