BaseDynamicGrid.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Media;
  9. using System.Windows.Media.Imaging;
  10. using FastReport.Editor;
  11. using InABox.Core;
  12. using Syncfusion.Data;
  13. using static InABox.DynamicGrid.IDynamicGrid;
  14. using Selection = InABox.Core.Selection;
  15. namespace InABox.DynamicGrid
  16. {
  17. public abstract class BaseDynamicGrid : ContentControl
  18. {
  19. public static readonly DependencyProperty UseWaitCursorProperty =
  20. DependencyProperty.Register(nameof(UseWaitCursor), typeof(bool), typeof(BaseDynamicGrid));
  21. protected enum ClipAction
  22. {
  23. Cut,
  24. Copy
  25. }
  26. public BaseDynamicGrid()
  27. {
  28. UseWaitCursor = true;
  29. }
  30. public bool UseWaitCursor
  31. {
  32. get => (bool)GetValue(UseWaitCursorProperty);
  33. set => SetValue(UseWaitCursorProperty, value);
  34. }
  35. public static Brush SelectionBackground { get; set; }
  36. public static Brush SelectionForeground { get; set; }
  37. public static Brush FilterBackground { get; set; }
  38. static BaseDynamicGrid()
  39. {
  40. SelectionForeground = new SolidColorBrush(Colors.Black);
  41. SelectionBackground = new SolidColorBrush(Colors.Silver);
  42. FilterBackground = new SolidColorBrush(Color.FromArgb(0xFF, 0xE9, 0xF7, 0xC9));
  43. }
  44. }
  45. public abstract class BaseDynamicGrid<T> : BaseDynamicGrid, IDynamicGrid where T : BaseObject, new()
  46. {
  47. public delegate void ValidateEvent(object sender, T[] items, List<string> errors);
  48. public event OnPrintData? OnPrintData;
  49. public event BeforeRefreshEventHandler? BeforeRefresh;
  50. protected void NotifyBeforeRefresh(BeforeRefreshEventArgs args) => BeforeRefresh?.Invoke(this, args);
  51. protected abstract bool OnBeforeRefresh();
  52. public event AfterRefreshEventHandler? AfterRefresh;
  53. protected void NotifyAfterRefresh(AfterRefreshEventArgs args) => AfterRefresh?.Invoke(this, args);
  54. protected abstract void OnAfterRefresh();
  55. public abstract event EntitySaveEvent? OnAfterSave;
  56. public abstract event EntitySaveEvent? OnBeforeSave;
  57. public event OnDefineFilter? OnDefineFilter;
  58. public abstract event OnFilterRecord? OnFilterRecord;
  59. public event OnCreateItem? OnCreateItem;
  60. public abstract event OnCustomiseEditor<T>? OnCustomiseEditor;
  61. public virtual event OnCustomiseColumns? OnCustomiseColumns;
  62. public abstract event OnDoubleClick? OnDoubleClick;
  63. public OnGetDynamicGridRowStyle? OnGetRowStyle { get; set; }
  64. public ValidateEvent? OnValidate;
  65. protected DynamicGridRowStyleSelector<T> RowStyleSelector;
  66. public event IDynamicGrid.ReconfigureEvent? OnReconfigure;
  67. public BaseDynamicGrid()
  68. {
  69. Options = new FluentList<DynamicGridOption>();
  70. Options.OnChanged += OptionsChanged;
  71. RowStyleSelector = GetRowStyleSelector();
  72. RowStyleSelector.GetStyle += (row, style) => GetRowStyle(row, style);
  73. HiddenColumns = new List<Expression<Func<T, object?>>>();
  74. }
  75. private void DefaultOptions_OnChanged(object sender, EventArgs args)
  76. {
  77. Reconfigure();
  78. }
  79. /// <summary>
  80. /// Initialise things like custom buttons; called once during construction.
  81. /// </summary>
  82. protected abstract void Init();
  83. protected abstract void DoReconfigure(FluentList<DynamicGridOption> options);
  84. /// <summary>
  85. /// Configure custom buttons and options.
  86. /// </summary>
  87. private void Reconfigure(FluentList<DynamicGridOption> options)
  88. {
  89. options.BeginUpdate().Clear();
  90. DoReconfigure(options);
  91. OnReconfigure?.Invoke(options);
  92. options.EndUpdate();
  93. }
  94. public void Reconfigure()
  95. {
  96. Reconfigure(Options);
  97. }
  98. public void Reconfigure(ReconfigureEvent onReconfigure)
  99. {
  100. OnReconfigure += onReconfigure;
  101. Reconfigure();
  102. }
  103. public bool HasOption(DynamicGridOption option, IEnumerable<DynamicGridOption>? options = null) => (options ?? Options).Contains(option);
  104. bool IDynamicGrid.HasOption(InABox.DynamicGrid.DynamicGridOption option) => HasOption(option, null);
  105. public List<Expression<Func<T, object?>>> HiddenColumns { get; }
  106. public void InitialiseEditorForm(IDynamicEditorForm editor, object[] items, Func<Type, CoreTable>? pageDataHandler = null, bool preloadPages = false)
  107. {
  108. InitialiseEditorForm(editor, items.Cast<T>().ToArray(), pageDataHandler, preloadPages);
  109. }
  110. public virtual bool EditItems(object[] items, Func<Type, CoreTable>? PageDataHandler = null, bool PreloadPages = false)
  111. {
  112. var values = items.Cast<T>().ToArray();
  113. return EditItems(values, PageDataHandler, PreloadPages);
  114. }
  115. //public abstract bool DirectEdit(CoreTable data);
  116. private FluentList<DynamicGridOption> Options { get; }
  117. public DynamicGridColumns MasterColumns { get; protected set; }
  118. public DynamicGridColumns VisibleColumns { get; protected set; }
  119. public CoreTable Data { get; set; }
  120. public virtual void ConfigureColumns(DynamicGridColumns columns)
  121. {
  122. OnCustomiseColumns?.Invoke(this, columns);
  123. }
  124. public abstract CoreRow[] SelectedRows { get; set; }
  125. public abstract void AddVisualFilter(string column, string value, FilterType filtertype = FilterType.Contains);
  126. public abstract Button AddButton(string caption, BitmapImage? image, string? tooltip, Func<Button, CoreRow[], bool> action,
  127. DynamicGridButtonPosition position = DynamicGridButtonPosition.Left);
  128. public virtual double RowHeight { get; set; }
  129. public virtual double HeaderHeight { get; set; }
  130. public new virtual double FontSize { get; set; }
  131. public void AddHiddenColumn(string column)
  132. {
  133. var expression = CoreUtils.CreateLambdaExpression<T>(column);
  134. HiddenColumns.Add(expression);
  135. }
  136. public abstract int DesiredWidth();
  137. public abstract void Refresh(bool reloadcolumns, bool reloaddata);
  138. public abstract void UpdateRow<TType>(CoreRow row, string column, TType value, bool refresh = true);
  139. public abstract void UpdateRow<T, TType>(CoreRow row, Expression<Func<T, TType>> column, TType value, bool refresh = true);
  140. protected abstract DynamicGridRowStyleSelector<T> GetRowStyleSelector();
  141. protected virtual DynamicGridStyle GetRowStyle(CoreRow row, DynamicGridStyle style)
  142. {
  143. return OnGetRowStyle != null ? OnGetRowStyle(row, style) : style;
  144. }
  145. public abstract void InitialiseEditorForm(IDynamicEditorForm editor, T[] items, Func<Type, CoreTable>? pageDataHandler = null, bool preloadPages = false);
  146. public abstract bool EditItems(T[] items, Func<Type, CoreTable>? PageDataHandler = null, bool PreloadPages = false);
  147. public Filter<T>? DefineFilter()
  148. {
  149. if (OnDefineFilter is null)
  150. return null;
  151. var result = OnDefineFilter.Invoke(typeof(T)) as Filter<T>;
  152. return result;
  153. }
  154. protected virtual T CreateItem()
  155. {
  156. var result = new T();
  157. OnCreateItem?.Invoke(this, result);
  158. return result;
  159. }
  160. protected virtual void DoPrint(object sender)
  161. {
  162. OnPrintData?.Invoke(sender);
  163. }
  164. protected abstract void OptionsChanged(object sender, EventArgs args);
  165. public IEnumerable<TType> ExtractValues<TType>(Expression<Func<T, TType>> column, Selection selection)
  166. {
  167. var result = selection == Selection.None
  168. ? new TType[] { }
  169. : selection == Selection.Selected
  170. ? SelectedRows.Select(r => r.Get(column)).ToArray()
  171. : Data.ExtractValues(column);
  172. return result;
  173. }
  174. }
  175. }