DynamicColumnGrid.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading;
  5. using InABox.Core;
  6. namespace InABox.DynamicGrid;
  7. public class DynamicColumnGrid : DynamicGrid<DynamicGridColumn>
  8. {
  9. public DynamicColumnGrid()
  10. {
  11. Columns = new DynamicGridColumns();
  12. }
  13. protected override void Init()
  14. {
  15. ActionColumns.Add(new DynamicRowMovementColumn(DynamicRowMovement.Up, SwapRows));
  16. ActionColumns.Add(new DynamicRowMovementColumn(DynamicRowMovement.Down, SwapRows));
  17. var column = MasterColumns.FirstOrDefault(x => string.Equals(x.ColumnName, nameof(DynamicGridColumn.ColumnName)));
  18. if(column is not null && column.Editor is DynamicColumnNameEditor edit)
  19. {
  20. edit.ColumnNames = () => ProcessColumns().Select(x => x.ColumnName).ToArray();
  21. }
  22. }
  23. protected override void DoReconfigure(DynamicGridOptions options)
  24. {
  25. options.RecordCount = true;
  26. options.MultiSelect = true;
  27. options.AddRows = true;
  28. options.EditRows = true;
  29. options.DeleteRows = true;
  30. options.DragRows = true;
  31. }
  32. public Type Type { get; set; }
  33. public DynamicGridColumns Columns { get; }
  34. public bool DirectEdit { get; set; }
  35. private bool SwapRows(int row1, int row2)
  36. {
  37. var item = Columns[row1];
  38. Columns.Remove(item);
  39. Columns.Insert(row2, item);
  40. return true;
  41. }
  42. protected override void MoveRows(CoreRow[] rows, int index)
  43. {
  44. var targetCol = index < Columns.Count ? Columns[index] : null;
  45. var cols = LoadItems(rows);
  46. foreach(var col in cols)
  47. {
  48. Columns.Remove(col);
  49. }
  50. if(targetCol is not null)
  51. {
  52. var idx = Columns.IndexOf(targetCol);
  53. Columns.InsertRange(idx, cols);
  54. }
  55. else
  56. {
  57. Columns.AddRange(cols);
  58. }
  59. Refresh(false, true);
  60. }
  61. protected override void DoAdd(bool openEditorOnDirectEdit = false)
  62. {
  63. if(DynamicGridColumnNameSelectorGrid.SelectColumnName(ProcessColumns().Select(x => x.ColumnName).ToArray(), out var column))
  64. {
  65. var item = CreateItem();
  66. var prop = DatabaseSchema.Property(Type, column);
  67. item.ColumnName = column;
  68. if(prop is not null)
  69. {
  70. item.Width = prop.Editor.Width;
  71. item.Alignment = prop.Editor.Alignment;
  72. item.Format = prop.Editor.Format;
  73. item.Editor = prop.Editor.CloneEditor();
  74. item.Caption = prop.Caption;
  75. }
  76. SaveItem(item);
  77. DoChanged();
  78. Refresh(false, true);
  79. }
  80. }
  81. protected override void DoValidate(DynamicGridColumn[] items, List<string> errors)
  82. {
  83. base.DoValidate(items, errors);
  84. if (items.Any(x => string.IsNullOrWhiteSpace(x.ColumnName)))
  85. errors.Add("[ColumnName] must not be blank!");
  86. }
  87. protected override Dictionary<string, object?> EditorValueChanged(IDynamicEditorForm editor, DynamicGridColumn[] items, string name, object value)
  88. {
  89. var changes = base.EditorValueChanged(editor, items, name, value);
  90. if(name == nameof(DynamicGridColumn.ColumnName) && value is string columnName)
  91. {
  92. var prop = DatabaseSchema.Property(Type, columnName);
  93. if(prop is not null)
  94. {
  95. foreach(var item in items)
  96. {
  97. CoreUtils.MonitorChanges(item, () =>
  98. {
  99. item.Width = prop.Editor.Width;
  100. item.Alignment = prop.Editor.Alignment;
  101. item.Format = prop.Editor.Format;
  102. item.Editor = prop.Editor.CloneEditor();
  103. item.Caption = prop.Caption;
  104. }, changes);
  105. }
  106. }
  107. }
  108. return changes;
  109. }
  110. private IEnumerable<DynamicGridColumn> ProcessColumns()
  111. {
  112. var result = new List<DynamicGridColumn>();
  113. var cols = new DynamicGridColumns();
  114. cols.ExtractColumns(Type);
  115. foreach (var col in cols)
  116. {
  117. if (col.Editor == null)
  118. continue;
  119. if (col.Editor is NullEditor)
  120. continue;
  121. if (col.Editor.Visible != Visible.Hidden)
  122. {
  123. result.Add(col);
  124. continue;
  125. }
  126. if (!DirectEdit)
  127. continue;
  128. if (col.Editor.Editable.IsEditable() && col.ColumnName.Split('.').Length <= 2)
  129. result.Add(col);
  130. }
  131. result.Sort((a, b) => a.ColumnName.CompareTo(b.ColumnName));
  132. return result;
  133. }
  134. protected override void DefineLookups(ILookupEditorControl sender, DynamicGridColumn[] items, bool async = true)
  135. {
  136. if (Type != null && sender.ColumnName.Equals("ColumnName"))
  137. {
  138. var results = new CoreTable();
  139. results.Columns.Add(new CoreColumn { ColumnName = sender.ColumnName, DataType = typeof(string) });
  140. results.Columns.Add(new CoreColumn { ColumnName = "Display", DataType = typeof(string) });
  141. var cols = ProcessColumns();
  142. foreach (var col in cols)
  143. {
  144. var row = results.NewRow();
  145. row[sender.ColumnName] = col.ColumnName;
  146. row["Display"] = col.ColumnName;
  147. results.Rows.Add(row);
  148. }
  149. sender.LoadLookups(results);
  150. }
  151. else
  152. {
  153. base.DefineLookups(sender, items, async);
  154. }
  155. }
  156. #region Save / Load
  157. protected override void Reload(
  158. Filters<DynamicGridColumn> criteria, Columns<DynamicGridColumn> columns, ref SortOrder<DynamicGridColumn>? sort,
  159. CancellationToken token, Action<CoreTable, Exception?> action)
  160. {
  161. var result = new CoreTable();
  162. if (columns == null || columns.Count == 0)
  163. result.LoadColumns(typeof(DynamicGridColumn));
  164. else
  165. result.LoadColumns(columns);
  166. result.LoadRows(Columns);
  167. action.Invoke(result, null);
  168. }
  169. public override DynamicGridColumn LoadItem(CoreRow row)
  170. {
  171. var index = Data.Rows.IndexOf(row);
  172. return Columns[index];
  173. }
  174. public override void SaveItem(DynamicGridColumn item)
  175. {
  176. try
  177. {
  178. var prop = DatabaseSchema.Property(Type, item.ColumnName);
  179. item.Editor = prop.Editor;
  180. }
  181. catch (Exception e)
  182. {
  183. Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
  184. }
  185. if (!Columns.Contains(item))
  186. Columns.Add(item);
  187. }
  188. public override void DeleteItems(params CoreRow[] rows)
  189. {
  190. foreach (var row in rows.OrderByDescending(x => x.Index))
  191. Columns.RemoveAt(row.Index);
  192. }
  193. #endregion
  194. }