DynamicGridMaskColumn.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Media;
  9. using System.Windows.Media.Imaging;
  10. using InABox.Core;
  11. using InABox.WPF;
  12. using Microsoft.Xaml.Behaviors;
  13. using Syncfusion.UI.Xaml.Grid;
  14. namespace InABox.DynamicGrid;
  15. public class DynamicGridMaskColumnButtonClickArgs
  16. {
  17. public object? Value { get; set; }
  18. public DynamicGridMaskColumnButtonClickArgs(object? value)
  19. {
  20. Value = value;
  21. }
  22. }
  23. public enum DynamicGridMaskColumnButtonPosition
  24. {
  25. Left,
  26. Right
  27. }
  28. public class DynamicGridMaskColumnButton
  29. {
  30. public BitmapImage? Image { get; set; }
  31. public Visibility Visibility { get; set; }
  32. public DynamicGridMaskColumnButtonPosition Position { get; set; } = DynamicGridMaskColumnButtonPosition.Right;
  33. public Action<DynamicGridMaskColumnButton,DynamicGridMaskColumnButtonClickArgs>? Clicked { get; set; }
  34. public object? DoClick(object? value)
  35. {
  36. var args = new DynamicGridMaskColumnButtonClickArgs(value);
  37. Clicked?.Invoke(this, args);
  38. return args.Value;
  39. }
  40. }
  41. public abstract class DynamicGridMaskColumn<TEntity, TEditor> : DynamicGridEditorColumn<TEntity, TEditor, GridTemplateColumn>
  42. where TEntity : BaseObject
  43. where TEditor : class,new()
  44. {
  45. protected abstract Behavior? CreateBehaviour();
  46. protected abstract IValueConverter? CreateConverter();
  47. protected override void Configure(GridTemplateColumn column, TEditor editor)
  48. {
  49. var converter = CreateConverter();
  50. column.CellTemplate = TemplateGenerator.CreateDataTemplate
  51. (
  52. () =>
  53. {
  54. var result = new Label
  55. {
  56. HorizontalContentAlignment = Column.TextAlignment == TextAlignment.Left
  57. ? HorizontalAlignment.Left
  58. : Column.TextAlignment == TextAlignment.Center
  59. ? HorizontalAlignment.Center
  60. : HorizontalAlignment.Right,
  61. VerticalContentAlignment = VerticalAlignment.Center
  62. };
  63. var binding = new Binding()
  64. {
  65. Path = new PropertyPath(MappingName),
  66. Converter = converter
  67. };
  68. result.SetBinding(Label.ContentProperty, binding);
  69. return result;
  70. }
  71. );
  72. column.EditTemplate = TemplateGenerator.CreateDataTemplate
  73. (
  74. () =>
  75. {
  76. var border = new Border()
  77. {
  78. BorderBrush = new SolidColorBrush(Colors.Gray),
  79. BorderThickness = new Thickness(0.75),
  80. Padding = new Thickness(0),
  81. Margin = new Thickness(0)
  82. };
  83. var dock = new DockPanel();
  84. dock.SourceUpdated += OnSourceUpdated;
  85. dock.TargetUpdated += OnTargetUpdated;
  86. border.Child = dock;
  87. var textbox = new TextBox
  88. {
  89. CharacterCasing = CharacterCasing.Upper,
  90. TextAlignment = Column.TextAlignment,
  91. BorderThickness = new Thickness(0),
  92. //Padding = new Thickness(2, 0, 0, 0),
  93. VerticalContentAlignment = VerticalAlignment.Center,
  94. Background = new SolidColorBrush(Colors.White)
  95. };
  96. textbox.SetBinding(TextBox.TextProperty, new Binding()
  97. {
  98. Path = new PropertyPath(MappingName),
  99. Converter = converter,
  100. NotifyOnSourceUpdated = true,
  101. NotifyOnTargetUpdated = true,
  102. });
  103. var behaviour = CreateBehaviour();
  104. if (behaviour != null)
  105. Interaction.GetBehaviors(textbox).Add(behaviour);
  106. textbox.SetValue(FocusManagerHelper.FocusedElementProperty, true);
  107. textbox.SetValue(DockPanel.DockProperty,Dock.Left);
  108. var defs = CreateButtons();
  109. if (defs?.Any() == true)
  110. {
  111. foreach (var def in defs)
  112. {
  113. Button button = new Button()
  114. {
  115. Tag = def,
  116. Content = new Image() { Source = def.Image },
  117. Padding = new Thickness(2),
  118. Width = 25,
  119. BorderThickness = new Thickness(0),
  120. Background = new SolidColorBrush(Colors.White),
  121. Visibility = def.Visibility,
  122. };
  123. button.Click += (sender, args) =>
  124. {
  125. var cvt = CreateConverter();
  126. var val = cvt != null
  127. ? cvt.ConvertBack(textbox.Text, typeof(object), null, CultureInfo.CurrentCulture)
  128. : textbox.Text;
  129. val = def.DoClick(val);
  130. textbox.Text = cvt != null
  131. ? cvt.Convert(val, typeof(String), null, CultureInfo.CurrentCulture) as String ?? ""
  132. : val?.ToString() ?? "";
  133. textbox.GetBindingExpression(TextBox.TextProperty)?.UpdateSource();
  134. button.Content = new Image() { Source = def.Image };
  135. button.Visibility = def.Visibility;
  136. };
  137. button.SetValue(DockPanel.DockProperty,def.Position == DynamicGridMaskColumnButtonPosition.Left ? Dock.Left : Dock.Right);
  138. dock.Children.Add(button);
  139. }
  140. }
  141. dock.Children.Add(textbox);
  142. return border;
  143. }
  144. );
  145. column.SetCellBoundValue = false;
  146. }
  147. protected virtual DynamicGridMaskColumnButton[]? CreateButtons()
  148. {
  149. return null;
  150. }
  151. private void OnTargetUpdated(object? sender, DataTransferEventArgs e)
  152. {
  153. if (sender is DockPanel dock && e.Source is TextBox textbox && e.Property == TextBox.TextProperty)
  154. {
  155. var buttons = dock?.Children.OfType<Button>().ToArray();
  156. var defs = buttons?.Select(x => x.Tag).OfType<DynamicGridMaskColumnButton>()?.ToArray();
  157. if (defs?.Any() == true)
  158. {
  159. var cvt = CreateConverter();
  160. var val = cvt != null
  161. ? cvt.ConvertBack(textbox.Text, typeof(object), null, CultureInfo.CurrentCulture)
  162. : textbox.Text;
  163. UpdateButtons(val, defs);
  164. if (buttons != null)
  165. foreach (var button in buttons)
  166. {
  167. var def = button.Tag as DynamicGridMaskColumnButton;
  168. button.Content = new Image() { Source = def?.Image };
  169. button.Visibility = def?.Visibility ?? Visibility.Collapsed;
  170. }
  171. }
  172. }
  173. }
  174. protected virtual void UpdateButtons(object? value, DynamicGridMaskColumnButton[]? buttons)
  175. {
  176. }
  177. private void OnSourceUpdated(object? sender, DataTransferEventArgs e)
  178. {
  179. if (sender is DockPanel dock && e.Source is TextBox textbox && e.Property == TextBox.TextProperty)
  180. {
  181. var buttons = dock?.Children.OfType<Button>().ToArray();
  182. SourceUpdated(textbox.Text, buttons ?? new Button[] { });
  183. }
  184. }
  185. protected virtual void SourceUpdated(string text, Button[] buttons)
  186. {
  187. }
  188. protected DynamicGridMaskColumn(DynamicGridColumn definition) : base(definition)
  189. {
  190. }
  191. }