GridControlEx.cs 53 KB

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