DynamicColumnGrid.cs 7.1 KB

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