DFMultiSignatureControl.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. using InABox.Core;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows.Controls;
  8. using System.Windows.Media.Effects;
  9. using System.Windows.Media.Imaging;
  10. using System.Windows.Media;
  11. using System.Windows;
  12. using InABox.WPF;
  13. namespace InABox.DynamicGrid
  14. {
  15. public class DFMultiSignatureControl : DynamicFormFieldControl<DFLayoutMultiSignaturePad, DFLayoutMultiSignaturePadProperties, Dictionary<string, byte[]>>
  16. {
  17. private Grid Grid = null!; // Late-initialised
  18. private Grid Images = null!; // Late-initialised
  19. protected override FrameworkElement Create()
  20. {
  21. Grid = new Grid();
  22. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
  23. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  24. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
  25. Grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
  26. Grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
  27. var imagesScroll = new ScrollViewer
  28. {
  29. HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
  30. VerticalScrollBarVisibility = ScrollBarVisibility.Disabled,
  31. Background = new SolidColorBrush(Colors.Gray)
  32. };
  33. Images = new Grid { Height = 150 };
  34. Images.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
  35. Images.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
  36. imagesScroll.Content = Images;
  37. var clearButton = new Button
  38. {
  39. Content = "Clear",
  40. Margin = new Thickness(0, 5, 0, 0),
  41. Width = 60,
  42. Height = 35
  43. };
  44. clearButton.Click += MultiSignatureClear_Click;
  45. var addButton = new Button
  46. {
  47. Content = "Add",
  48. Margin = new Thickness(0, 5, 0, 0),
  49. Width = 60,
  50. Height = 35
  51. };
  52. addButton.Click += MultiSignatureAdd_Click;
  53. imagesScroll.SetGridPosition(0, 0, 1, 3);
  54. clearButton.SetGridPosition(1, 0, 1, 1);
  55. addButton.SetGridPosition(1, 2, 1, 1);
  56. Grid.Children.Add(imagesScroll);
  57. Grid.Children.Add(clearButton);
  58. Grid.Children.Add(addButton);
  59. return Grid;
  60. }
  61. private void AddMultiSignature(BitmapSource? source, string name)
  62. {
  63. var image = new Image();
  64. if (source != null)
  65. {
  66. image.Source = source;
  67. var label = new Label
  68. {
  69. Content = name.ToUpper(),
  70. VerticalContentAlignment = VerticalAlignment.Center,
  71. VerticalAlignment = VerticalAlignment.Stretch,
  72. HorizontalContentAlignment = HorizontalAlignment.Center
  73. };
  74. var column = Images.ColumnDefinitions.Count;
  75. var menu = new ContextMenu();
  76. menu.AddItem("Remove Signature", null, image, MultiSignatureRemove_Click);
  77. Images.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
  78. image.ContextMenu = menu;
  79. label.ContextMenu = menu;
  80. image.SetGridPosition(0, column, 1, 1);
  81. label.SetGridPosition(1, column, 1, 1);
  82. Images.Children.Add(image);
  83. Images.Children.Add(label);
  84. }
  85. }
  86. private void MultiSignatureAdd_Click(object sender, RoutedEventArgs e)
  87. {
  88. var window = new SignaturePadWindow(null, true);
  89. if (window.ShowDialog() == true)
  90. {
  91. var sigName = window.SignatureName.ToUpper().Trim();
  92. if (string.IsNullOrWhiteSpace(sigName))
  93. {
  94. MessageBox.Show("Name cannot be empty!");
  95. }
  96. if (Images.Children.Cast<UIElement>().Any(x => x is Label lbl && (string)lbl.Content == sigName))
  97. {
  98. MessageBox.Show("A signature with that name already exists!");
  99. }
  100. else
  101. {
  102. AddMultiSignature(window.Image, window.SignatureName);
  103. ChangeField();
  104. }
  105. }
  106. }
  107. private void MultiSignatureRemove_Click(Image image)
  108. {
  109. var imageColumn = Grid.GetColumn(image);
  110. var removes = new List<UIElement>();
  111. foreach (var child in Images.Children)
  112. {
  113. if (child is UIElement el)
  114. {
  115. var column = Grid.GetColumn(el);
  116. if (column == imageColumn)
  117. removes.Add(el);
  118. else if (column > imageColumn)
  119. Grid.SetColumn(el, column - 1);
  120. }
  121. }
  122. foreach (var element in removes)
  123. {
  124. Images.Children.Remove(element);
  125. }
  126. ChangeField();
  127. }
  128. private void MultiSignatureClear_Click(object sender, RoutedEventArgs e)
  129. {
  130. if (Images.Children.Count > 0)
  131. {
  132. Images.Children.Clear();
  133. ChangeField();
  134. }
  135. }
  136. public override Dictionary<string, byte[]> GetValue()
  137. {
  138. var columns = Images.Children.Cast<UIElement>().GroupBy(x => Grid.GetColumn(x));
  139. var data = new Dictionary<string, byte[]>();
  140. foreach (var column in columns)
  141. {
  142. if (column.FirstOrDefault(x => x is Image) is Image image
  143. && column.FirstOrDefault(x => x is Label) is Label label)
  144. {
  145. var imgData = EmbeddedImageUtilities.SaveImageToBytes(image, false, new PngBitmapEncoder());
  146. if (imgData != null && label.Content is string str)
  147. {
  148. data.Add(str, imgData);
  149. }
  150. }
  151. }
  152. return data;
  153. }
  154. public override void SetValue(Dictionary<string, byte[]>? value)
  155. {
  156. Images.Children.Clear();
  157. if (value is IDictionary<string, byte[]> data)
  158. {
  159. foreach (var (name, imgData) in data)
  160. {
  161. AddMultiSignature(ImageUtils.BitmapImageFromBytes(imgData), name);
  162. }
  163. }
  164. }
  165. protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
  166. {
  167. base.OnPropertyChanged(e);
  168. if (e.Property == IsEnabledProperty)
  169. {
  170. Grid.RowDefinitions[1].Height = (bool)e.NewValue
  171. ? GridLength.Auto
  172. : new GridLength(0);
  173. }
  174. }
  175. protected override bool IsEmpty() => Images.Children.Count == 0;
  176. }
  177. }