IDynamicGridGridUIComponent.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. using ICSharpCode.AvalonEdit.Indentation;
  2. using InABox.Clients;
  3. using InABox.Core;
  4. using sun.tools.tree;
  5. using Syncfusion.Data;
  6. using Syncfusion.UI.Xaml.Grid;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Diagnostics.CodeAnalysis;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using System.Windows;
  14. using System.Windows.Forms.VisualStyles;
  15. namespace InABox.DynamicGrid;
  16. public interface IDynamicGridUIComponentColumn
  17. {
  18. double GetWidth(IDynamicGridGridUIComponent component);
  19. DynamicGridColumnWidthUnitType GetWidthUnit(IDynamicGridGridUIComponent component);
  20. }
  21. public class DynamicGridColumnUIComponentColumn(DynamicColumnBase column) : IDynamicGridUIComponentColumn
  22. {
  23. public DynamicColumnBase Column { get; set; } = column;
  24. public double GetWidth(IDynamicGridGridUIComponent component)
  25. {
  26. if (Column is DynamicImageColumn dic)
  27. {
  28. return component.RowHeight;
  29. }
  30. else if (Column is DynamicActionColumn dac)
  31. {
  32. return dac.Width;
  33. }
  34. else if (Column is DynamicGridColumn dgc)
  35. {
  36. return dgc.Width;
  37. }
  38. else
  39. {
  40. return 0;
  41. }
  42. }
  43. public DynamicGridColumnWidthUnitType GetWidthUnit(IDynamicGridGridUIComponent component)
  44. {
  45. if (Column is DynamicImageColumn dic)
  46. {
  47. return DynamicGridColumnWidthUnitType.Pixel;
  48. }
  49. else if (Column is DynamicActionColumn dac)
  50. {
  51. return DynamicGridColumnWidthUnitType.Pixel;
  52. }
  53. else if (Column is DynamicGridColumn dgc)
  54. {
  55. return dgc.Width == 0 ? DynamicGridColumnWidthUnitType.Star : dgc.WidthUnit;
  56. }
  57. else
  58. {
  59. return 0;
  60. }
  61. }
  62. }
  63. public interface IDynamicGridGridUIComponent
  64. {
  65. IList<IDynamicGridUIComponentColumn> ColumnList { get; }
  66. int RowHeight { get; }
  67. }
  68. internal static class DynamicGridGridUIComponentExtension
  69. {
  70. public static IEnumerable<KeyValuePair<int, double>> CalculateColumnSizes(this IDynamicGridGridUIComponent component, double width, bool manualautosize = true)
  71. {
  72. var fAvailWidth = width - (SystemParameters.VerticalScrollBarWidth);
  73. //if (Data.Rows.Count * (DataGrid.RowHeight + 1) + DataGrid.HeaderRowHeight > height + 0.5F)
  74. //if (height < DataGrid.AutoScroller.VScrollBar.Maximum)
  75. // fAvailWidth -= (SystemParameters.VerticalScrollBarWidth + 0.75);
  76. var fCurWidth = 0.0;
  77. var autoColumnTotal = 0.0;
  78. var colWidths = new double[component.ColumnList.Count];
  79. var units = new DynamicGridColumnWidthUnitType[component.ColumnList.Count];
  80. for (var i = 0; i < component.ColumnList.Count; i++)
  81. {
  82. var col = component.ColumnList[i];
  83. var unit = col.GetWidthUnit(component);
  84. var colWidth = col.GetWidth(component);
  85. if(unit == DynamicGridColumnWidthUnitType.Star && colWidth == 0)
  86. {
  87. colWidth = 1;
  88. }
  89. colWidths[i] = colWidth;
  90. units[i] = unit;
  91. if (unit != DynamicGridColumnWidthUnitType.Star)
  92. fCurWidth += Math.Max(0.0F, colWidth);
  93. else
  94. autoColumnTotal += colWidth;
  95. }
  96. if (manualautosize && autoColumnTotal > 0)
  97. {
  98. var fAutoWidth = (fAvailWidth - fCurWidth) / autoColumnTotal;
  99. for (var i = 0; i < component.ColumnList.Count; i++)
  100. if (units[i] == DynamicGridColumnWidthUnitType.Star)
  101. colWidths[i] = Math.Max(fAutoWidth * colWidths[i], 100);
  102. }
  103. return colWidths.WithIndex();
  104. }
  105. public static int DesiredWidth(this IDynamicGridGridUIComponent component)
  106. {
  107. var result = 0;
  108. for (var i = 0; i < component.ColumnList.Count; i++)
  109. {
  110. var col = component.ColumnList[i];
  111. var colWidth = col.GetWidth(component);
  112. result += colWidth > 0 ? (int)Math.Round(colWidth) : 300;
  113. }
  114. return result;
  115. }
  116. private static Dictionary<Type, Type>? _editorColumnMap;
  117. private static Dictionary<Type, Type> EditorColumnMap
  118. {
  119. get
  120. {
  121. _editorColumnMap ??= CoreUtils.Entities.Where(x => x.IsClass && x.HasInterface<IDynamicGridEditorColumn>()).Select(x =>
  122. {
  123. var def = x.GetSuperclassDefinition(typeof(DynamicGridEditorColumn<,,>))!;
  124. return new KeyValuePair<Type, Type>(def.GenericTypeArguments[0], x);
  125. }).ToDictionary();
  126. return _editorColumnMap;
  127. }
  128. }
  129. public static bool CreateEditorColumn<T>(this IDynamicGridGridUIComponent component, DynamicGridColumn column,
  130. [NotNullWhen(true)] out IDynamicGridEditorColumn? newcol)
  131. {
  132. newcol = null;
  133. if (EditorColumnMap.TryGetValue(column.Editor.GetType(), out var colType))
  134. {
  135. if(colType.GetInterfaceDefinition(typeof(IDynamicGridEditorColumn<>)) is Type genericInterface)
  136. {
  137. newcol = Activator.CreateInstance(colType.MakeGenericType(typeof(T)), column) as IDynamicGridEditorColumn;
  138. }
  139. else
  140. {
  141. newcol = Activator.CreateInstance(colType, column) as IDynamicGridEditorColumn;
  142. }
  143. if(newcol is IDynamicGridEditorColumn gridCol)
  144. {
  145. gridCol.UpdateUIComponent(component);
  146. }
  147. return newcol is not null;
  148. }
  149. else
  150. {
  151. return false;
  152. }
  153. }
  154. public static bool CreateEditorColumn(this IDynamicGridGridUIComponent component, DynamicGridColumn column,
  155. [NotNullWhen(true)] out IDynamicGridEditorColumn? newcol)
  156. {
  157. newcol = null;
  158. if (EditorColumnMap.TryGetValue(column.Editor.GetType(), out var colType))
  159. {
  160. if(colType.GetInterfaceDefinition(typeof(IDynamicGridEditorColumn<>)) is not Type genericInterface)
  161. {
  162. newcol = Activator.CreateInstance(colType, column) as IDynamicGridEditorColumn;
  163. }
  164. if(newcol is IDynamicGridEditorColumn gridCol)
  165. {
  166. gridCol.UpdateUIComponent(component);
  167. }
  168. return newcol is not null;
  169. }
  170. else
  171. {
  172. return false;
  173. }
  174. }
  175. private static bool FilterByPredicate(CoreRow row, string column, FilterPredicate predicate)
  176. {
  177. var value = row[column];
  178. var vStr = value?.ToString()?.ToLower() ?? "";
  179. var pValue = predicate.FilterValue;
  180. var pStr = pValue?.ToString()?.ToLower() ?? "";
  181. return predicate.FilterType switch
  182. {
  183. FilterType.Contains => vStr.Contains(pStr),
  184. FilterType.EndsWith => vStr.EndsWith(pStr),
  185. FilterType.Equals => vStr.Equals(pStr),
  186. FilterType.GreaterThan => vStr.CompareTo(pStr) > 0,
  187. FilterType.GreaterThanOrEqual => vStr.CompareTo(pStr) >= 0,
  188. FilterType.LessThan => vStr.CompareTo(pStr) < 0,
  189. FilterType.LessThanOrEqual => vStr.CompareTo(pStr) <= 0,
  190. FilterType.NotContains => !vStr.Contains(pStr),
  191. FilterType.NotEndsWith => !vStr.EndsWith(pStr),
  192. FilterType.NotEquals => !vStr.Equals(pStr),
  193. FilterType.NotStartsWith => !vStr.StartsWith(pStr),
  194. FilterType.StartsWith => vStr.StartsWith(pStr),
  195. _ => true,
  196. };
  197. }
  198. public static Func<CoreRow, bool>? ConvertColumnPredicates(DynamicGridColumn gridColumn, IEnumerable<FilterPredicate> predicates)
  199. {
  200. Func<CoreRow, bool>? rowPredicate = null;
  201. foreach (var predicate in predicates)
  202. {
  203. var p = (CoreRow row) => FilterByPredicate(row, gridColumn.ColumnName, predicate);
  204. if(rowPredicate is null)
  205. {
  206. rowPredicate = p;
  207. }
  208. else
  209. {
  210. var prevP = rowPredicate;
  211. if(predicate.PredicateType == PredicateType.And)
  212. {
  213. rowPredicate = r => prevP(r) && p(r);
  214. }
  215. else
  216. {
  217. rowPredicate = r => prevP(r) || p(r);
  218. }
  219. }
  220. }
  221. return rowPredicate;
  222. }
  223. }