DynamicGridCommon.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Windows.Controls;
  5. using InABox.Core;
  6. using InABox.Wpf;
  7. using Syncfusion.Data;
  8. namespace InABox.DynamicGrid;
  9. public abstract class DynamicColumnBase : BaseObject, IDynamicColumnBase
  10. {
  11. public void DoEntityChanged(string columnname, Dictionary<string,object?> changes)
  12. {
  13. EntityChanged?.Invoke(this, new DynamicColumnEntityChangedEventArgs(columnname, changes));
  14. }
  15. public event DynamicColumnEntityChangedEvent? EntityChanged;
  16. public object? Tag { get; set; }
  17. }
  18. public class DynamicGridOptions
  19. {
  20. public event Action? OnChanged;
  21. private int _enabled = 0;
  22. private bool _changed = false;
  23. public bool Enabled
  24. {
  25. get => _enabled == 0;
  26. set
  27. {
  28. if (value)
  29. EndUpdate();
  30. else
  31. BeginUpdate();
  32. }
  33. }
  34. public DynamicGridOptions Clear()
  35. {
  36. BeginUpdate();
  37. AddRows = false;
  38. EditRows = false;
  39. DeleteRows = false;
  40. FilterRows = false;
  41. SelectColumns = false;
  42. ExportData = false;
  43. ImportData = false;
  44. MultiSelect = false;
  45. DragSource = false;
  46. DragTarget = false;
  47. ReorderRows = false;
  48. DirectEdit = false;
  49. ShowHelp = false;
  50. Print = false;
  51. RecordCount = false;
  52. HideDatabaseFilters = false;
  53. HideDirectEditButton = false;
  54. PageSize = 0;
  55. NonModalEditorHost = null;
  56. ReadOnly = false;
  57. return EndUpdate();
  58. }
  59. public DynamicGridOptions BeginUpdate()
  60. {
  61. ++_enabled;
  62. return this;
  63. }
  64. private DynamicGridOptions Changed()
  65. {
  66. if (_enabled == 0)
  67. {
  68. _changed = false;
  69. OnChanged?.Invoke();
  70. }
  71. else
  72. {
  73. _changed = true;
  74. }
  75. return this;
  76. }
  77. public DynamicGridOptions EndUpdate()
  78. {
  79. --_enabled;
  80. if(_changed)
  81. {
  82. Changed();
  83. }
  84. return this;
  85. }
  86. private bool _addRows;
  87. public bool AddRows
  88. {
  89. get => _addRows && !ReadOnly;
  90. set
  91. {
  92. if(_addRows != value)
  93. {
  94. _addRows = value;
  95. Changed();
  96. }
  97. }
  98. }
  99. private bool _editRows;
  100. public bool EditRows
  101. {
  102. get => _editRows && !ReadOnly;
  103. set
  104. {
  105. if(_editRows != value)
  106. {
  107. _editRows = value;
  108. Changed();
  109. }
  110. }
  111. }
  112. private bool _deleteRows;
  113. public bool DeleteRows
  114. {
  115. get => _deleteRows && !ReadOnly;
  116. set
  117. {
  118. if(_deleteRows != value)
  119. {
  120. _deleteRows = value;
  121. Changed();
  122. }
  123. }
  124. }
  125. private bool _filterRows;
  126. public bool FilterRows
  127. {
  128. get => _filterRows;
  129. set
  130. {
  131. if(_filterRows != value)
  132. {
  133. _filterRows = value;
  134. Changed();
  135. }
  136. }
  137. }
  138. private bool _selectColumns;
  139. public bool SelectColumns
  140. {
  141. get => _selectColumns;
  142. set
  143. {
  144. if(_selectColumns != value)
  145. {
  146. _selectColumns = value;
  147. Changed();
  148. }
  149. }
  150. }
  151. private bool _exportData;
  152. public bool ExportData
  153. {
  154. get => _exportData;
  155. set
  156. {
  157. if(_exportData != value)
  158. {
  159. _exportData = value;
  160. Changed();
  161. }
  162. }
  163. }
  164. private bool _importData;
  165. public bool ImportData
  166. {
  167. get => _importData;
  168. set
  169. {
  170. if(_importData != value)
  171. {
  172. _importData = value;
  173. Changed();
  174. }
  175. }
  176. }
  177. private bool _multiSelect;
  178. public bool MultiSelect
  179. {
  180. get => _multiSelect;
  181. set
  182. {
  183. if(_multiSelect != value)
  184. {
  185. _multiSelect = value;
  186. Changed();
  187. }
  188. }
  189. }
  190. private bool _dragSource;
  191. public bool DragSource
  192. {
  193. get => _dragSource;
  194. set
  195. {
  196. if(_dragSource != value)
  197. {
  198. _dragSource = value;
  199. Changed();
  200. }
  201. }
  202. }
  203. private bool _dragTarget;
  204. public bool DragTarget
  205. {
  206. get => _dragTarget;
  207. set
  208. {
  209. if(_dragTarget != value)
  210. {
  211. _dragTarget = value;
  212. Changed();
  213. }
  214. }
  215. }
  216. private bool _reorderRows;
  217. /// <summary>
  218. /// Allow re-ordering rows within this grid, including cut+paste functionality, and row dragging.
  219. /// This is never <see langword="true"/> if <see cref="EditRows"/> is not enabled.
  220. /// </summary>
  221. /// <remarks>
  222. /// <see cref="DragSource"/> and <see cref="DragTarget"/> deal with external dragging, whereas this deals with internal dragging.
  223. /// <br/>
  224. /// Note that this requires the <see cref="DynamicGrid{T}.MoveRows(CoreRow[], int)"/> function; the default implementation relies on the items
  225. /// being <see cref="ISequenceable"/>, but this can be overriden.
  226. /// </remarks>
  227. public bool ReorderRows
  228. {
  229. get => _reorderRows && EditRows;
  230. set
  231. {
  232. if(_reorderRows != value)
  233. {
  234. _reorderRows = value;
  235. Changed();
  236. }
  237. }
  238. }
  239. private bool _directEdit;
  240. public bool DirectEdit
  241. {
  242. get => _directEdit && !ReadOnly;
  243. set
  244. {
  245. if(_directEdit != value)
  246. {
  247. _directEdit = value;
  248. Changed();
  249. }
  250. }
  251. }
  252. private bool _showHelp;
  253. public bool ShowHelp
  254. {
  255. get => _showHelp;
  256. set
  257. {
  258. if(_showHelp != value)
  259. {
  260. _showHelp = value;
  261. Changed();
  262. }
  263. }
  264. }
  265. private bool _print;
  266. public bool Print
  267. {
  268. get => _print;
  269. set
  270. {
  271. if(_print != value)
  272. {
  273. _print = value;
  274. Changed();
  275. }
  276. }
  277. }
  278. private bool _recordCount;
  279. public bool RecordCount
  280. {
  281. get => _recordCount;
  282. set
  283. {
  284. if(_recordCount != value)
  285. {
  286. _recordCount = value;
  287. Changed();
  288. }
  289. }
  290. }
  291. private bool _hideDatabaseFilters;
  292. public bool HideDatabaseFilters
  293. {
  294. get => _hideDatabaseFilters;
  295. set
  296. {
  297. if(_hideDatabaseFilters != value)
  298. {
  299. _hideDatabaseFilters = value;
  300. Changed();
  301. }
  302. }
  303. }
  304. private bool _hideDirectEditButton;
  305. public bool HideDirectEditButton
  306. {
  307. get => _hideDirectEditButton;
  308. set
  309. {
  310. if(_hideDirectEditButton != value)
  311. {
  312. _hideDirectEditButton = value;
  313. Changed();
  314. }
  315. }
  316. }
  317. private ISubPanelHost? _nonModalEditorHost;
  318. public ISubPanelHost? NonModalEditorHost
  319. {
  320. get => _nonModalEditorHost;
  321. set
  322. {
  323. if(_nonModalEditorHost != value)
  324. {
  325. _nonModalEditorHost = value;
  326. Changed();
  327. }
  328. }
  329. }
  330. private int _pageSize = 0;
  331. /// <summary>
  332. /// The page size for loading data in pages; set to 0 for no paging functionality.
  333. /// </summary>
  334. public int PageSize
  335. {
  336. get => _pageSize;
  337. set
  338. {
  339. if(_pageSize != value)
  340. {
  341. _pageSize = value;
  342. Changed();
  343. }
  344. }
  345. }
  346. public bool _readOnly = false;
  347. /// <summary>
  348. /// Specifies whether this grid is "read-only"; if this is <see langword="true"/>, then the <see cref="AddRows"/>, <see
  349. /// cref="EditRows"/>, <see cref="DeleteRows"/> and <see cref="DirectEdit"/> will be disabled.
  350. /// </summary>
  351. /// <remarks>
  352. /// Setting this property can improve performance, since it allows the grid to not load <see cref="LookupFactory.RequiredColumns(Type)"/>.
  353. /// </remarks>
  354. public bool ReadOnly
  355. {
  356. get => _readOnly;
  357. set
  358. {
  359. if(_readOnly != value)
  360. {
  361. _readOnly = value;
  362. Changed();
  363. }
  364. }
  365. }
  366. }
  367. public delegate bool OnFilterRecord(CoreRow row);
  368. public delegate void OnCreateItem(object sender, BaseObject item);
  369. public delegate bool OnAfterCreateItem(object sender, BaseObject item);
  370. public delegate T OnCreateItem<T>();
  371. public delegate void OnDefineLookup(ILookupEditorControl editor);
  372. public delegate void OnGridCustomiseEditor(DynamicEditorGrid sender, DynamicGridColumn column, BaseEditor editor);
  373. public delegate void OnFormCustomiseEditor(IDynamicEditorForm sender, object[] items, DynamicGridColumn column, BaseEditor editor);
  374. public delegate void ValidateEvent<T>(DynamicGrid<T> sender, T[] items, List<string> errors)
  375. where T : BaseObject, new();
  376. /// <summary>
  377. ///
  378. /// </summary>
  379. /// <typeparam name="T"></typeparam>
  380. /// <param name="sender"></param>
  381. /// <param name="items">The array of items being edited; <see langword="null"/> is synonymous with an empty array.</param>
  382. /// <param name="column"></param>
  383. /// <param name="editor"></param>
  384. public delegate void OnCustomiseEditor<T>(IDynamicEditorForm sender, T[]? items, DynamicGridColumn column, BaseEditor editor);
  385. public delegate void OnCustomiseEditor(IDynamicEditorForm sender, object[]? items, DynamicGridColumn column, BaseEditor editor);
  386. public delegate void OnLoadEditorButtons<T>(T item, DynamicEditorButtons buttons);
  387. public delegate void OnReconfigureEditors(DynamicEditorGrid sender);
  388. public delegate void OnCreateEditorControl(string column, BaseEditor editor, IDynamicEditorControl control);
  389. public class AfterEditorValueChangedArgs
  390. {
  391. public string ColumnName { get; set; }
  392. public Dictionary<string, object?> ChangedValues { get; set; }
  393. public AfterEditorValueChangedArgs(string columnName, Dictionary<string, object?> changedValues)
  394. {
  395. ColumnName = columnName;
  396. ChangedValues = changedValues;
  397. }
  398. }
  399. public delegate Dictionary<string, object?>? OnAfterEditorValueChanged(DynamicEditorGrid sender, AfterEditorValueChangedArgs args);
  400. //public delegate void OnGridChanged(IDynamicGrid sender);
  401. public delegate void OnLoadPage(IDynamicEditorPage page);
  402. public delegate void OnSelectPage(DynamicEditorGrid sender, BaseObject[]? items);
  403. public delegate void OnUnloadPage(IDynamicEditorPage page, bool saved);
  404. public delegate void OnCustomiseColumns(object sender, DynamicGridColumns columns);
  405. public delegate BaseEditor? OnGetEditor(DynamicGridColumn column);
  406. public delegate decimal OnGetEditorSequence(DynamicGridColumn column);
  407. public delegate IFilter? OnDefineLookupFilter(Type type, string column);
  408. public delegate IFilter? OnDefineFilter(Type type);
  409. public delegate IList<string>? OnValidateData(IDynamicEditorForm sender, BaseObject[] items);
  410. public delegate void OnPrintData(object sender);
  411. public delegate void EntitySaveEvent(IDynamicEditorForm editor, BaseObject[] items);
  412. public delegate bool DynamicGridButtonClickEvent(Button button, CoreRow[] rows);
  413. public delegate void OnContextMenuOpening<TKey>(CoreTreeNode<TKey>? node, ContextMenu menu);
  414. public class DynamicGridSelectionEventArgs : CancelEventArgs
  415. {
  416. public DynamicGridSelectionEventArgs(CoreRow[]? rows)
  417. {
  418. Rows = rows;
  419. }
  420. public CoreRow[]? Rows { get; }
  421. }
  422. public delegate void SelectItemHandler(object sender, DynamicGridSelectionEventArgs e);
  423. public delegate void OnDoubleClick(object sender, HandledEventArgs args);
  424. public class DynamicGridCellClickEventArgs : HandledEventArgs
  425. {
  426. public CoreRow? Row { get; set; }
  427. public DynamicColumnBase? Column { get; set; }
  428. public DynamicGridCellClickEventArgs(CoreRow? row, DynamicColumnBase? column)
  429. {
  430. Row = row;
  431. Column = column;
  432. }
  433. }
  434. public delegate void OnCellDoubleClick(object sender, DynamicGridCellClickEventArgs args);
  435. public class BeforeRefreshEventArgs : CancelEventArgs { }
  436. public delegate void BeforeRefreshEventHandler(object sender, BeforeRefreshEventArgs args);
  437. public class AfterRefreshEventArgs : EventArgs { }
  438. public delegate void AfterRefreshEventHandler(object sender, AfterRefreshEventArgs args);
  439. public class GenerateColumnsEventArgs
  440. {
  441. public DynamicGridColumns Columns { get; private set; }
  442. public GenerateColumnsEventArgs(DynamicGridColumns columns)
  443. {
  444. Columns = columns;
  445. }
  446. }
  447. public delegate void GenerateColumnsEvent(object sender, GenerateColumnsEventArgs args);
  448. public class SaveColumnsEventArgs
  449. {
  450. public DynamicGridColumns Columns { get; private set; }
  451. public SaveColumnsEventArgs(DynamicGridColumns columns)
  452. {
  453. Columns = columns;
  454. }
  455. }
  456. public delegate void SaveColumnsEvent(object sender, SaveColumnsEventArgs args);
  457. public class GetAvailableColumnsEventArgs(IEnumerable<DynamicGridColumn> columns)
  458. {
  459. public IEnumerable<DynamicGridColumn> Columns { get; set; } = columns;
  460. }
  461. public delegate void GetAvailableColumnsEvent(GetAvailableColumnsEventArgs args);