DFMultiImageControl.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. using InABox.Core;
  2. using InABox.WPF;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using System.Windows;
  11. using System.Windows.Controls;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Effects;
  14. using System.Windows.Media.Imaging;
  15. namespace InABox.DynamicGrid
  16. {
  17. public class DFMultiImageControl : DynamicFormFieldControl<DFLayoutMultiImage, DFLayoutMultiImageProperties, List<byte[]>>
  18. {
  19. private Grid Grid = null!; // Late-initialised
  20. private StackPanel Images = null!; // Late-initialised
  21. private bool Enabled = true;
  22. static DFMultiImageControl()
  23. {
  24. IsEnabledProperty.OverrideMetadata(
  25. typeof(DFMultiImageControl),
  26. new UIPropertyMetadata(
  27. true,
  28. ControlIsEnabledChanged));
  29. }
  30. private static void ControlIsEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
  31. {
  32. var control = (DFMultiImageControl)obj;
  33. control.IsEnabled = true;
  34. control.Enabled = (bool)e.NewValue;
  35. }
  36. protected override FrameworkElement Create()
  37. {
  38. Grid = new Grid();
  39. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
  40. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
  41. Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
  42. Grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
  43. Grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
  44. var imagesScroll = new ScrollViewer
  45. {
  46. HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
  47. VerticalScrollBarVisibility = ScrollBarVisibility.Disabled,
  48. Background = new SolidColorBrush(Colors.Gray)
  49. };
  50. Images = new StackPanel { Orientation = Orientation.Horizontal, Height = 200 };
  51. imagesScroll.Content = Images;
  52. var clearButton = new Button
  53. {
  54. Content = "Clear",
  55. Margin = new Thickness(0, 5, 0, 0),
  56. Width = 60,
  57. Height = 35
  58. };
  59. clearButton.Click += MultiImageClear_Click;
  60. var addButton = new Button
  61. {
  62. Content = "Add",
  63. Margin = new Thickness(0, 5, 0, 0),
  64. Width = 60,
  65. Height = 35
  66. };
  67. addButton.Click += MultiImageAdd_Click;
  68. imagesScroll.SetGridPosition(0, 0, 1, 3);
  69. clearButton.SetGridPosition(1, 0, 1, 1);
  70. addButton.SetGridPosition(1, 2, 1, 1);
  71. Grid.Children.Add(imagesScroll);
  72. Grid.Children.Add(clearButton);
  73. Grid.Children.Add(addButton);
  74. return Grid;
  75. }
  76. private void AddMultiImage(byte[] data)
  77. {
  78. var border = new Border
  79. {
  80. Effect = new DropShadowEffect
  81. {
  82. ShadowDepth = 0,
  83. BlurRadius = 10
  84. }
  85. };
  86. var image = new Image
  87. {
  88. Margin = new Thickness(5)
  89. };
  90. var source = ImageUtils.BitmapImageFromBytes(data);
  91. if (source != null)
  92. {
  93. image.Source = source;
  94. var menu = new ContextMenu();
  95. menu.AddItem("View Image", null, image, MultiImageView_Click);
  96. menu.AddItem("Remove Image", null, border, MultiImageRemove_Click);
  97. image.ContextMenu = menu;
  98. image.ContextMenuOpening += (sender, args) =>
  99. {
  100. if (!Enabled) args.Handled = true;
  101. };
  102. border.Child = image;
  103. Images.Children.Add(border);
  104. }
  105. }
  106. private void MultiImageClear_Click(object sender, RoutedEventArgs e)
  107. {
  108. if (Images.Children.Count > 0)
  109. {
  110. Images.Children.Clear();
  111. ChangeField();
  112. }
  113. }
  114. private void MultiImageView_Click(Image element)
  115. {
  116. var filename = Path.ChangeExtension(Path.GetTempFileName(), ".jpg");
  117. File.WriteAllBytes(filename, EmbeddedImageUtilities.SaveImageToBytes(element, false, new JpegBitmapEncoder()) ?? Array.Empty<byte>());
  118. var gsProcessInfo = new ProcessStartInfo();
  119. gsProcessInfo.Verb = "open";
  120. gsProcessInfo.WindowStyle = ProcessWindowStyle.Normal;
  121. gsProcessInfo.FileName = filename;
  122. gsProcessInfo.UseShellExecute = true;
  123. Process.Start(gsProcessInfo);
  124. }
  125. private void MultiImageRemove_Click(FrameworkElement element)
  126. {
  127. Images.Children.Remove(element);
  128. ChangeField();
  129. }
  130. private void MultiImageAdd_Click(object sender, RoutedEventArgs e)
  131. {
  132. if (EmbeddedImageUtilities.SelectImageFile(out var data))
  133. {
  134. AddMultiImage(data);
  135. ChangeField();
  136. }
  137. }
  138. public override List<byte[]> GetValue()
  139. {
  140. var data = new List<byte[]>();
  141. foreach (var image in Images.FindVisualChildren<Image>())
  142. {
  143. var imgData = EmbeddedImageUtilities.SaveImageToBytes(image, false, new JpegBitmapEncoder());
  144. if (imgData != null)
  145. {
  146. data.Add(imgData);
  147. }
  148. }
  149. return data;
  150. }
  151. public override void SetValue(List<byte[]>? value)
  152. {
  153. Images.Children.Clear();
  154. if (value is IEnumerable<byte[]> data)
  155. {
  156. foreach (var imgData in data)
  157. {
  158. AddMultiImage(imgData);
  159. }
  160. }
  161. }
  162. protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
  163. {
  164. base.OnPropertyChanged(e);
  165. if (e.Property == IsEnabledProperty)
  166. {
  167. Grid.RowDefinitions[1].Height = (bool)e.NewValue
  168. ? GridLength.Auto
  169. : new GridLength(0);
  170. }
  171. }
  172. protected override bool IsEmpty() => Images.Children.Count == 0;
  173. }
  174. }