DynamicGridCodePopupColumn.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Linq;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using InABox.Clients;
  9. using InABox.Core;
  10. using InABox.WPF;
  11. using Syncfusion.Data;
  12. using Syncfusion.UI.Xaml.Grid;
  13. using Syncfusion.UI.Xaml.TreeGrid;
  14. using Columns = InABox.Core.Columns;
  15. namespace InABox.DynamicGrid;
  16. public class DynamicGridCodePopupColumn<TEntity>(DynamicGridColumn definition) : DynamicGridEditorColumn<CodePopupEditor, GridTemplateColumn, TreeGridTemplateColumn>(definition), IDynamicGridEditorColumn<TEntity>
  17. where TEntity : BaseObject, new()
  18. {
  19. public Func<BaseObject?>? GetEntity { get; set; }
  20. private IColumns GetLinkColumns(Type type, string prefix)
  21. {
  22. var prefixwithstop = $"{prefix}.";
  23. var cols = Columns.None(type);
  24. var props = DatabaseSchema.Properties(typeof(TEntity))
  25. .Where(x => x.Name.StartsWith(prefixwithstop, StringComparison.OrdinalIgnoreCase));
  26. foreach (var prop in props)
  27. cols.Add(prop.Name.Remove(0,prefixwithstop.Length));
  28. return cols;
  29. }
  30. private Tuple<DataTemplate, DataTemplate> GetTemplates(CodePopupEditor editor)
  31. {
  32. var prefix = string.Join(".", Definition.ColumnName.Split('.').SkipLast(1));
  33. var colname = String.IsNullOrWhiteSpace(editor.CodeColumn)
  34. ? DatabaseSchema.Properties(editor.Type).FirstOrDefault(x => x.Editor is UniqueCodeEditor)?.Name ?? ""
  35. : editor.CodeColumn;
  36. var codecolname = prefix.IsNullOrWhiteSpace()
  37. ? colname
  38. : $"{prefix}.{colname}";
  39. ExtraColumns.Add(codecolname);
  40. codecolname = codecolname.Replace('.', '_');
  41. var cellTemplate = TemplateGenerator.CreateDataTemplate
  42. (
  43. () =>
  44. {
  45. var result = new Label();
  46. result.SetBinding(Label.ContentProperty, new Binding(codecolname));
  47. result.VerticalContentAlignment = VerticalAlignment.Center;
  48. return result;
  49. }
  50. );
  51. var editTemplate = TemplateGenerator.CreateDataTemplate
  52. (
  53. () =>
  54. {
  55. var result = new Grid();
  56. result.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
  57. result.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) });
  58. var textbox = new TextBox();
  59. textbox.CharacterCasing = CharacterCasing.Upper;
  60. textbox.SetBinding(TextBox.TextProperty, new Binding(codecolname));
  61. textbox.SetValue(Grid.ColumnProperty, 0);
  62. textbox.SetValue(Grid.ColumnSpanProperty, 2);
  63. textbox.Padding = new Thickness(2, 0, 0, 0);
  64. textbox.VerticalContentAlignment = VerticalAlignment.Center;
  65. textbox.PreviewKeyDown += (sender, args) => textbox.Tag = true;
  66. textbox.SetValue(FocusManagerHelper.FocusedElementProperty, true);
  67. textbox.Tag = false;
  68. textbox.TextChanged += (sender, args) =>
  69. {
  70. if (Equals(textbox.Tag, false))
  71. textbox.SelectAll();
  72. };
  73. // textbox.GotFocus += (sender, args) =>
  74. // textbox.SelectAll();
  75. textbox.LostFocus += (sender, args) =>
  76. {
  77. if (sender is TextBox { Tag: true } box &&
  78. (sender as FrameworkElement)?.DataContext is DataRowView view)
  79. {
  80. if (String.IsNullOrWhiteSpace(box.Text))
  81. {
  82. var table = new CoreTable();
  83. var columns = GetLinkColumns(editor.Type, prefix);
  84. table.LoadColumns(columns);
  85. var newrow = table.NewRow(true);
  86. UpdateCodePopupColumnValue(newrow,prefix);
  87. }
  88. else
  89. {
  90. var lookup = ClientFactory.CreateClient(editor.Type).Query(
  91. Filter.Create(editor.Type, colname, Operator.BeginsWith,
  92. box.Text),
  93. GetLinkColumns(editor.Type,prefix),
  94. null
  95. );
  96. if (lookup.Rows.Count == 1)
  97. UpdateCodePopupColumnValue(lookup.Rows[0], prefix);
  98. else
  99. PopupCodeList(editor.Type, prefix, codecolname, box.Text, GetLinkColumns(editor.Type,prefix));
  100. }
  101. }
  102. };
  103. result.Children.Add(textbox);
  104. var button = new Button();
  105. button.Content = "..";
  106. button.Width = 25;
  107. button.SetValue(Grid.ColumnProperty, 1);
  108. button.Margin = new Thickness(1);
  109. button.BorderThickness = new Thickness(0.75, 0, 0, 0);
  110. button.Tag = textbox;
  111. button.Click += (sender, args) =>
  112. {
  113. PopupCodeList(editor.Type, prefix, codecolname, (button.Tag as TextBox).Text, GetLinkColumns(editor.Type,prefix));
  114. };
  115. result.Children.Add(button);
  116. return result;
  117. }
  118. );
  119. return new Tuple<DataTemplate, DataTemplate>(cellTemplate, editTemplate);
  120. }
  121. protected override void Configure(TreeGridTemplateColumn column, CodePopupEditor editor)
  122. {
  123. var (cell, edit) = GetTemplates(editor);
  124. column.CellTemplate = cell;
  125. column.EditTemplate = edit;
  126. column.SetCellBoundValue = false;
  127. }
  128. protected override void Configure(GridTemplateColumn column, CodePopupEditor editor)
  129. {
  130. var (cell, edit) = GetTemplates(editor);
  131. column.CellTemplate = cell;
  132. column.EditTemplate = edit;
  133. column.SetCellBoundValue = false;
  134. }
  135. private void PopupCodeList(Type type, string prefix, string codecolname, string value, IColumns columns)
  136. {
  137. var entity = GetEntity?.Invoke() as TEntity;
  138. if (entity != null)
  139. {
  140. var msdtype = typeof(MultiSelectDialog<>).MakeGenericType(type);
  141. var coltype = typeof(Columns<>).MakeGenericType(type);
  142. var cols = (Activator.CreateInstance(coltype, ColumnTypeFlags.IncludeID) as IColumns);
  143. var msd = Activator.CreateInstance(
  144. msdtype,
  145. new object?[]
  146. {
  147. LookupFactory.DefineLookupFilter(typeof(TEntity), type, prefix, new TEntity[] { entity }),
  148. cols,
  149. false
  150. }
  151. ) as IMultiSelectDialog;
  152. if (msd.ShowDialog(codecolname, value, FilterType.StartsWith))
  153. {
  154. var row = msd.Data().Rows.FirstOrDefault();
  155. if (row != null)
  156. {
  157. row = ClientFactory.CreateClient(type)
  158. .Query(Filter.Create(type, "ID", Operator.IsEqualTo, row.Get<Guid>("ID")), columns)
  159. .Rows
  160. .FirstOrDefault();
  161. if (row != null)
  162. UpdateCodePopupColumnValue(row,prefix);
  163. }
  164. }
  165. }
  166. }
  167. private void UpdateCodePopupColumnValue(CoreRow row, string prefix)
  168. {
  169. var dict = row.ToDictionary();
  170. var updates = dict.ToDictionary(x => $"{prefix}.{x.Key}", x => x.Value);
  171. this.UpdateData(updates);
  172. }
  173. }