DynamicEditorControl.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. using System.Collections.Generic;
  2. using System.ComponentModel;
  3. using System.Linq;
  4. using System.Windows;
  5. using System.Windows.Controls;
  6. using System.Windows.Media;
  7. using InABox.Core;
  8. using static ICSharpCode.AvalonEdit.Document.TextDocumentWeakEventManager;
  9. namespace InABox.DynamicGrid
  10. {
  11. public delegate void EditorControlValueChangedHandler(IDynamicEditorControl sender, Dictionary<string, object> values);
  12. public interface IDynamicEditorControl
  13. {
  14. string ColumnName { get; set; }
  15. bool Loaded { get; set; }
  16. bool Changed { get; set; }
  17. BaseEditor EditorDefinition { get; set; }
  18. bool IsEnabled { get; set; }
  19. void SetFocus();
  20. int DesiredHeight();
  21. event EditorControlValueChangedHandler OnEditorValueChanged;
  22. void Configure();
  23. void SetEnabled(bool enabled);
  24. void SetVisible(bool enabled);
  25. void SetValue(string property, object? value);
  26. object? GetValue(string property);
  27. }
  28. public interface ILookupEditorControl : IDynamicEditorControl
  29. {
  30. Dictionary<string, string> OtherColumns { get; }
  31. event OnDefineLookup OnDefineLookups;
  32. event OnLookupsDefined OnLookupsDefined;
  33. void LoadLookups(CoreTable values);
  34. }
  35. public interface IPopupEditorControl
  36. {
  37. Dictionary<string, string> OtherColumns { get; }
  38. event OnDefineFilter OnDefineFilter;
  39. }
  40. public abstract class BaseDynamicEditorControl : ContentControl, IDynamicEditorControl
  41. {
  42. public static readonly DependencyProperty ColumnNameProperty =
  43. DependencyProperty.Register(nameof(ColumnName), typeof(string), typeof(BaseDynamicEditorControl));
  44. public static readonly DependencyProperty ColorProperty =
  45. DependencyProperty.Register("Color", typeof(Color), typeof(BaseDynamicEditorControl));
  46. public new static readonly DependencyProperty IsEnabledProperty =
  47. DependencyProperty.Register(nameof(IsEnabled), typeof(bool), typeof(BaseDynamicEditorControl));
  48. private BaseEditor _editordefinition;
  49. public BaseDynamicEditorControl()
  50. {
  51. Color = Colors.LightYellow;
  52. }
  53. public Color Color
  54. {
  55. get => (Color)GetValue(ColorProperty);
  56. set
  57. {
  58. SetValue(ColorProperty, value);
  59. if (EditorDefinition != null)
  60. SetColor(Color);
  61. }
  62. }
  63. public string ColumnName
  64. {
  65. get => (string)GetValue(ColumnNameProperty);
  66. set => SetValue(ColumnNameProperty, value);
  67. }
  68. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  69. public BaseEditor EditorDefinition
  70. {
  71. get => _editordefinition;
  72. set
  73. {
  74. _editordefinition = value;
  75. Content = CreateEditor();
  76. SetColor(Color);
  77. }
  78. }
  79. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  80. public bool Loaded { get; set; }
  81. public abstract bool Changed { get; set; }
  82. public virtual event EditorControlValueChangedHandler OnEditorValueChanged;
  83. public abstract int DesiredHeight();
  84. public abstract void SetFocus();
  85. public virtual void Configure()
  86. {
  87. }
  88. public abstract void SetEnabled(bool enabled);
  89. public abstract void SetVisible(bool visible);
  90. public abstract void SetValue(string property, object? value);
  91. /// <summary>
  92. ///
  93. /// </summary>
  94. /// <param name="property">The full property name of the entity being edited.</param>
  95. /// <returns></returns>
  96. public abstract object? GetValue(string property);
  97. public abstract Dictionary<string, object?> GetValues();
  98. public new bool IsEnabled
  99. {
  100. get => (bool)GetValue(IsEnabledProperty);
  101. set
  102. {
  103. SetValue(IsEnabledProperty, value);
  104. SetEnabled(value);
  105. }
  106. }
  107. protected abstract FrameworkElement CreateEditor();
  108. public abstract int DesiredWidth();
  109. public abstract void SetColor(Color color);
  110. protected List<Button> CreateButtons(out bool bDisableEditor)
  111. {
  112. var buttons = new List<Button>();
  113. bDisableEditor = false;
  114. if (EditorDefinition != null && EditorDefinition is IButtonEditor)
  115. {
  116. var ce = (IButtonEditor)EditorDefinition;
  117. if (ce.Buttons != null)
  118. foreach (var ceb in ce.Buttons.Reverse())
  119. {
  120. if (ceb.DisableEditor)
  121. bDisableEditor = true;
  122. var button = new Button
  123. {
  124. HorizontalAlignment = HorizontalAlignment.Left,
  125. VerticalAlignment = VerticalAlignment.Stretch,
  126. VerticalContentAlignment = VerticalAlignment.Center,
  127. HorizontalContentAlignment = HorizontalAlignment.Center,
  128. Content = ceb.Caption,
  129. Width = ceb.Width,
  130. Margin = new Thickness(5, 0, 0, 0),
  131. Padding = new Thickness(5, 0, 5, 0),
  132. Tag = ceb,
  133. IsEnabled = ceb.IsEnabled
  134. };
  135. button.Click += (o, e) =>
  136. {
  137. var b = (Button)o;
  138. var eb = b.Tag as EditorButton;
  139. eb.Click(this);
  140. };
  141. ceb.OnEnabled += (enabled) =>
  142. {
  143. button.IsEnabled = enabled;
  144. };
  145. buttons.Add(button);
  146. }
  147. }
  148. return buttons;
  149. }
  150. }
  151. public abstract class DynamicEditorControl<T> : BaseDynamicEditorControl
  152. {
  153. //{
  154. // get { return (EditorControlValueChangedHandler)GetValue(OnEditorValueChangedProperty); }
  155. // set { SetValue(OnEditorValueChangedProperty, value) }
  156. //}
  157. protected bool Updating;
  158. public DynamicEditorControl()
  159. {
  160. Loaded = false;
  161. OtherValues = new();
  162. MinHeight = 25;
  163. Focusable = false;
  164. }
  165. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  166. public override bool Changed { get; set; }
  167. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  168. public T Value
  169. {
  170. get => RetrieveValue();
  171. set => UpdateValue(value);
  172. }
  173. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  174. protected virtual Dictionary<string, object?> OtherValues { get; }
  175. //public static readonly DependencyProperty OnEditorValueChangedProperty =
  176. // DependencyProperty.Register(nameof(OnEditorValueChanged), typeof(EditorControlValueChangedHandler), typeof(DynamicEditorControl<T>));
  177. public override event EditorControlValueChangedHandler OnEditorValueChanged;
  178. protected void EditorValueChanged(IDynamicEditorControl sender, Dictionary<string, object> values) => OnEditorValueChanged?.Invoke(sender, values);
  179. protected virtual bool CheckChanged()
  180. {
  181. //Logger.Send(LogType.Information, "", string.Format("{0}({1}).CheckChanged()", GetType().EntityName().Split('.').Last(), ColumnName));
  182. if (Loaded && !Updating)
  183. {
  184. Updating = true;
  185. try
  186. {
  187. var values = new Dictionary<string, object>();
  188. var sColumn = string.IsNullOrEmpty(ColumnName) ? "" : ColumnName;
  189. values[sColumn] = RetrieveValue();
  190. foreach (var key in OtherValues.Keys)
  191. values[key] = OtherValues[key];
  192. OnEditorValueChanged?.Invoke(this, values);
  193. }
  194. finally
  195. {
  196. Changed = true;
  197. Updating = false;
  198. }
  199. }
  200. return Changed;
  201. }
  202. public override void SetValue(string property, object? value)
  203. {
  204. UpdateValue(value != null ? (T)value : default);
  205. }
  206. public override object? GetValue(string property)
  207. {
  208. return RetrieveValue();
  209. }
  210. public override Dictionary<string, object?> GetValues()
  211. {
  212. return new Dictionary<string, object?>
  213. {
  214. { ColumnName, RetrieveValue() }
  215. };
  216. }
  217. protected abstract T RetrieveValue();
  218. protected abstract void UpdateValue(T value);
  219. public override bool ShouldSerializeContent()
  220. {
  221. return false;
  222. }
  223. public override void SetEnabled(bool enabled)
  224. {
  225. if (Content is FrameworkElement element) element.IsEnabled = enabled;
  226. SetColor(enabled ? Color : Colors.WhiteSmoke);
  227. }
  228. public override void SetVisible(bool visible)
  229. {
  230. Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
  231. }
  232. }
  233. public abstract class DynamicEnclosedEditorControl<T> : BaseDynamicEditorControl
  234. where T : IEnclosedEntity
  235. {
  236. protected bool Updating;
  237. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  238. public override bool Changed { get; set; }
  239. public override event EditorControlValueChangedHandler? OnEditorValueChanged;
  240. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  241. protected virtual Dictionary<string, object?> OtherValues { get; }
  242. public DynamicEnclosedEditorControl()
  243. {
  244. Loaded = false;
  245. OtherValues = new();
  246. MinHeight = 25;
  247. Focusable = false;
  248. }
  249. protected virtual bool CheckChanged()
  250. {
  251. //Logger.Send(LogType.Information, "", string.Format("{0}({1}).CheckChanged()", GetType().EntityName().Split('.').Last(), ColumnName));
  252. if (Loaded && !Updating)
  253. {
  254. Updating = true;
  255. try
  256. {
  257. var values = new Dictionary<string, object>();
  258. var sColumn = string.IsNullOrEmpty(ColumnName) ? "" : ColumnName;
  259. foreach(var (k, v) in GetValues())
  260. {
  261. values[k] = v;
  262. }
  263. foreach (var key in OtherValues.Keys)
  264. values[key] = OtherValues[key];
  265. OnEditorValueChanged?.Invoke(this, values);
  266. }
  267. finally
  268. {
  269. Changed = true;
  270. Updating = false;
  271. }
  272. }
  273. return Changed;
  274. }
  275. public override void SetEnabled(bool enabled)
  276. {
  277. if(Content is FrameworkElement element) element.IsEnabled = enabled;
  278. SetColor(enabled ? Color : Colors.WhiteSmoke);
  279. }
  280. public override void SetVisible(bool visible)
  281. {
  282. Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
  283. }
  284. }
  285. }