CodePopupEditorControl.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Windows;
  5. using System.Windows.Controls;
  6. using System.Windows.Controls.Primitives;
  7. using System.Windows.Input;
  8. using System.Windows.Media;
  9. using InABox.Clients;
  10. using InABox.Core;
  11. namespace InABox.DynamicGrid;
  12. public class CodePopupEditorControl : DynamicEditorControl<Guid, CodePopupEditor>
  13. {
  14. static CodePopupEditorControl()
  15. {
  16. //DynamicEditorControlFactory.Register<CodePopupEditorControl, CodePopupEditor>();
  17. }
  18. private Type _type;
  19. private Guid _value = Guid.Empty;
  20. private TextBox Description;
  21. private TextBox Editor;
  22. private string origvalue = "";
  23. public string CodeColumn { get; set; }
  24. protected override FrameworkElement CreateEditor()
  25. {
  26. var Grid = new Grid
  27. {
  28. VerticalAlignment = VerticalAlignment.Stretch,
  29. HorizontalAlignment = HorizontalAlignment.Stretch
  30. };
  31. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(131, GridUnitType.Pixel) });
  32. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(19, GridUnitType.Pixel) });
  33. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  34. Editor = new TextBox
  35. {
  36. CharacterCasing = CharacterCasing.Upper,
  37. VerticalAlignment = VerticalAlignment.Stretch,
  38. VerticalContentAlignment = VerticalAlignment.Center,
  39. HorizontalAlignment = HorizontalAlignment.Stretch
  40. };
  41. Editor.BorderThickness = new Thickness(1,1,0,1);
  42. Editor.BorderBrush = new SolidColorBrush(Colors.Silver);
  43. Editor.SetValue(Grid.ColumnProperty, 0);
  44. Editor.SetValue(Grid.RowProperty, 0);
  45. Editor.PreviewKeyDown += Editor_PreviewKeyDown;
  46. Editor.GotFocus += Editor_GotFocus;
  47. Editor.AcceptsTab = true;
  48. Editor.LostFocus += Editor_LostFocus;
  49. Grid.Children.Add(Editor);
  50. var Select = new Button
  51. {
  52. VerticalAlignment = VerticalAlignment.Stretch,
  53. VerticalContentAlignment = VerticalAlignment.Center,
  54. HorizontalAlignment = HorizontalAlignment.Stretch,
  55. Content = "..",
  56. Focusable = false
  57. };
  58. Select.BorderThickness = new Thickness(1);
  59. Select.BorderBrush = new SolidColorBrush(Colors.DimGray);
  60. Select.SetValue(Grid.ColumnProperty, 1);
  61. Select.SetValue(Grid.RowProperty, 0);
  62. Select.Click += Select_Click;
  63. Grid.Children.Add(Select);
  64. Description = new TextBox
  65. {
  66. VerticalAlignment = VerticalAlignment.Stretch,
  67. VerticalContentAlignment = VerticalAlignment.Center,
  68. HorizontalAlignment = HorizontalAlignment.Stretch,
  69. Margin = new Thickness(5, 0, 0, 0),
  70. IsReadOnly = true,
  71. Focusable = false,
  72. Background = new SolidColorBrush(Colors.WhiteSmoke),
  73. BorderBrush = new SolidColorBrush(Colors.Silver)
  74. };
  75. Description.SetValue(Grid.ColumnProperty, 2);
  76. Description.SetValue(Grid.RowProperty, 0);
  77. Grid.Children.Add(Description);
  78. return Grid;
  79. }
  80. private void Editor_GotFocus(object sender, RoutedEventArgs e)
  81. {
  82. origvalue = Editor.Text;
  83. }
  84. private void Editor_LostFocus(object sender, RoutedEventArgs e)
  85. {
  86. if (Editor.Text.Equals(origvalue))
  87. return;
  88. if (string.IsNullOrEmpty(Editor.Text))
  89. {
  90. LookupValue(nameof(Entity.ID), Guid.Empty);
  91. CheckChanged();
  92. }
  93. else
  94. {
  95. var id = _value;
  96. LookupValue(CodeColumn, Editor.Text);
  97. if (id == Guid.Empty)
  98. CheckChanged();
  99. }
  100. }
  101. private void Editor_PreviewKeyDown(object sender, KeyEventArgs e)
  102. {
  103. if (e.Key.Equals(Key.Enter) || e.Key.Equals(Key.Tab))
  104. {
  105. if (string.IsNullOrEmpty(Editor.Text))
  106. {
  107. if (!Editor.Text.Equals(origvalue))
  108. {
  109. LookupValue("ID", Guid.Empty);
  110. CheckChanged();
  111. }
  112. Editor.MoveFocus(new TraversalRequest(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)
  113. ? FocusNavigationDirection.Previous
  114. : FocusNavigationDirection.Next));
  115. }
  116. else
  117. {
  118. if (!Editor.Text.Equals(origvalue))
  119. {
  120. var code = Editor.Text;
  121. LookupValue(CodeColumn, code);
  122. if (_value != Guid.Empty)
  123. {
  124. CheckChanged();
  125. Editor.MoveFocus(new TraversalRequest(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)
  126. ? FocusNavigationDirection.Previous
  127. : FocusNavigationDirection.Next));
  128. }
  129. else
  130. {
  131. if (DoSearch(code))
  132. Editor.MoveFocus(new TraversalRequest(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)
  133. ? FocusNavigationDirection.Previous
  134. : FocusNavigationDirection.Next));
  135. }
  136. }
  137. else
  138. {
  139. Editor.MoveFocus(new TraversalRequest(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)
  140. ? FocusNavigationDirection.Previous
  141. : FocusNavigationDirection.Next));
  142. }
  143. }
  144. e.Handled = true;
  145. }
  146. }
  147. private void Editor_PreviewKeyUp(object sender, KeyEventArgs e)
  148. {
  149. }
  150. private void Editor_KeyUp(object sender, KeyEventArgs e)
  151. {
  152. }
  153. private void Select_Click(object sender, RoutedEventArgs e)
  154. {
  155. DoSearch(Editor.Text);
  156. }
  157. private bool DoSearch(string code)
  158. {
  159. var result = false;
  160. if (_type != null)
  161. {
  162. var columns = LookupFactory.DefineLookupColumns(Host.GetEditorType(), _type, ColumnName);
  163. var list = new PopupList(_type, _value,
  164. columns.ColumnNames().Concat(CoreUtils.One(CodeColumn)).ToArray(),
  165. new Dictionary<string, string> { { CodeColumn, code } });
  166. list.OnDefineFilter += t => LookupFactory.DefineLookupFilter(Host.GetEditorType(), t, ColumnName, Host.GetItems());
  167. list.OnCustomiseGrid += grid =>
  168. {
  169. if (EditorDefinition.CanAdd)
  170. {
  171. grid.OnDoubleClick += (o, args) => args.Handled = true;
  172. grid.OnReconfigure += options =>
  173. {
  174. options.AddRows = Security.CanEdit(_type);
  175. options.EditRows = Security.CanEdit(_type);
  176. options.EditRows = Security.CanDelete(_type);
  177. options.ReadOnly = false;
  178. };
  179. grid.OnCreateItem += (_, item) =>
  180. {
  181. LookupFactory.OnCreateItem(Host.GetEditorType(), ColumnName, Host.GetItems(), item);
  182. EditorDefinition.OnCreateItem?.Invoke(item);
  183. };
  184. grid.Reconfigure();
  185. }
  186. };
  187. if (list.ShowDialog() == true)
  188. {
  189. result = true;
  190. _value = list.ID;
  191. foreach (var col in columns)
  192. OtherValues[col.Property] = list.OtherValues[col.Property];
  193. CheckChanged();
  194. Editor.Text = string.Format("{0}", list.OtherValues[CodeColumn]);
  195. origvalue = Editor.Text ?? "";
  196. var display = new Dictionary<string, object?>();
  197. foreach (var key in list.OtherValues.Keys.Where(x => !string.Equals(x, CodeColumn)))
  198. display[key] = list.OtherValues[key];
  199. Description.Text =
  200. LookupFactory.FormatLookup(_type, display, new[] { CodeColumn });
  201. }
  202. }
  203. return result;
  204. }
  205. public override int DesiredHeight()
  206. {
  207. return 25;
  208. }
  209. public override int DesiredWidth()
  210. {
  211. return int.MaxValue;
  212. }
  213. protected override Guid RetrieveValue()
  214. {
  215. return _value;
  216. }
  217. protected override void UpdateValue(Guid value)
  218. {
  219. var oldvalue = _value;
  220. _value = value;
  221. if (oldvalue != value)
  222. {
  223. if (Equals(value, Guid.Empty))
  224. SetEmptyValue();
  225. else
  226. LookupValue("ID", value);
  227. CheckChanged();
  228. }
  229. }
  230. private void SetEmptyValue()
  231. {
  232. Editor.Text = "";
  233. origvalue = "";
  234. Description.Text = "";
  235. }
  236. private void LookupValue(string column, object value)
  237. {
  238. var client = ClientFactory.CreateClient(_type);
  239. var columns = LookupFactory.DefineLookupColumns(Host.GetEditorType(), _type, ColumnName);
  240. columns.Add(CodeColumn);
  241. var sort = LookupFactory.DefineSort(_type);
  242. var filter = Filter.Create(_type, column).IsEqualTo(value);
  243. var lookup = client.Query(filter, columns, sort);
  244. var display = new Dictionary<string,object?>();
  245. var code = "";
  246. var id = Guid.Empty;
  247. var displaycols = LookupFactory.DefineLookupColumns(Host.GetEditorType(), _type, ColumnName).ColumnNames();
  248. var row = lookup.Rows.FirstOrDefault();
  249. row ??= lookup.NewRow(true);
  250. code = row[CodeColumn]?.ToString();
  251. id = row.Get<Guid>("ID");
  252. foreach (var col in displaycols.Where(x => !x.Equals("ID") && !x.Equals(CodeColumn)))
  253. display[col] = row[col];
  254. foreach(var col in columns)
  255. {
  256. OtherValues[col.Property] = row[col.Property];
  257. }
  258. _value = id;
  259. Editor.Text = code;
  260. origvalue = Editor.Text ?? "";
  261. Description.Text = LookupFactory.FormatLookup(_type, display, new[] { CodeColumn });
  262. }
  263. private string GetCodeColumn(Type type)
  264. {
  265. var prop = DatabaseSchema.Properties(type)
  266. .Where(x => x.Editor is UniqueCodeEditor && !x.HasParentEntityLink())
  267. .FirstOrDefault() ?? throw new Exception($"No code property for {type.EntityName()}");
  268. return prop.Name;
  269. }
  270. public override void Configure()
  271. {
  272. _type = EditorDefinition.Type;
  273. CodeColumn = !string.IsNullOrEmpty(EditorDefinition.CodeColumn) ? EditorDefinition.CodeColumn : GetCodeColumn(_type);
  274. }
  275. public override void SetFocus()
  276. {
  277. Editor.Focus();
  278. }
  279. public override void SetColor(Color color)
  280. {
  281. Editor.Background = IsEnabled ? new SolidColorBrush(color) : new SolidColorBrush(Colors.WhiteSmoke);
  282. }
  283. }