DynamicGridCodePopupColumn.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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> : DynamicGridEditorColumn<TEntity, CodePopupEditor, GridTemplateColumn, TreeGridTemplateColumn>
  17. where TEntity : BaseObject, new()
  18. {
  19. private IColumns GetLinkColumns(Type type, String prefix)
  20. {
  21. var prefixwithstop = $"{prefix.ToUpper()}.";
  22. var cols = Columns.None(type);
  23. var props = DatabaseSchema.Properties(typeof(TEntity))
  24. .Where(x => x.Name.ToUpper().StartsWith(prefixwithstop));
  25. foreach (var prop in props)
  26. cols.Add(prop.Name.Remove(0,prefixwithstop.Length));
  27. return cols;
  28. }
  29. private Tuple<DataTemplate, DataTemplate> GetTemplates(CodePopupEditor editor)
  30. {
  31. var prefix = String.Join(".", Definition.ColumnName.Split('.').Reverse().Skip(1).Reverse());
  32. var colname = String.IsNullOrWhiteSpace(editor.CodeColumn)
  33. ? CoreUtils.PropertyList(editor.Type, p => p.GetEditor() is UniqueCodeEditor)
  34. .FirstOrDefault()?.Name ?? ""
  35. : editor.CodeColumn;
  36. var codecolname = String.IsNullOrWhiteSpace(prefix)
  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 msd = Activator.CreateInstance(
  142. msdtype,
  143. new object?[]
  144. {
  145. LookupFactory.DefineLookupFilter(typeof(TEntity), type, prefix, new TEntity[] { entity }),
  146. columns,
  147. false
  148. }
  149. ) as IMultiSelectDialog;
  150. if (msd.ShowDialog(codecolname, value, FilterType.StartsWith))
  151. {
  152. var row = msd.Data().Rows.FirstOrDefault();
  153. if (row != null)
  154. UpdateCodePopupColumnValue(row,prefix);
  155. }
  156. }
  157. }
  158. private void UpdateCodePopupColumnValue(CoreRow row, string prefix)
  159. {
  160. var dict = row.ToDictionary();
  161. var updates = new Dictionary<String, object>();
  162. foreach (var key in dict.Keys)
  163. updates[$"{prefix}.{key}"] = dict[key];
  164. UpdateData(updates);
  165. }
  166. public DynamicGridCodePopupColumn(DynamicGridColumn definition) : base(definition)
  167. {
  168. }
  169. }