ClipboardPage.xaml.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Avalonia;
  5. using Avalonia.Controls;
  6. using Avalonia.Controls.Notifications;
  7. using Avalonia.Input;
  8. using Avalonia.Input.Platform;
  9. using Avalonia.Interactivity;
  10. using Avalonia.Media;
  11. using Avalonia.Media.Imaging;
  12. using Avalonia.Platform;
  13. using Avalonia.Platform.Storage;
  14. using Avalonia.Threading;
  15. namespace ControlCatalog.Pages
  16. {
  17. public partial class ClipboardPage : UserControl
  18. {
  19. private readonly DataFormat<byte[]> _customBinaryDataFormat =
  20. DataFormat.CreateBytesApplicationFormat("controlcatalog-binary-data");
  21. private INotificationManager? _notificationManager;
  22. private INotificationManager NotificationManager => _notificationManager
  23. ??= new WindowNotificationManager(TopLevel.GetTopLevel(this)!);
  24. private readonly DispatcherTimer _clipboardLastDataObjectChecker;
  25. private DataTransfer? _storedDataTransfer;
  26. private bool _checkingClipboardDataTransfer;
  27. private Bitmap _defaultImage;
  28. public ClipboardPage()
  29. {
  30. InitializeComponent();
  31. _clipboardLastDataObjectChecker =
  32. new DispatcherTimer(TimeSpan.FromSeconds(0.5), default, CheckLastDataObject);
  33. using var asset = AssetLoader.Open(new Uri("avares://ControlCatalog/Assets/image1.jpg"));
  34. _defaultImage = new Bitmap(asset);
  35. ClipboardImage.Source = _defaultImage;
  36. }
  37. private async void CopyText(object? sender, RoutedEventArgs args)
  38. {
  39. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  40. await clipboard.SetTextAsync(ClipboardContent.Text ?? string.Empty);
  41. }
  42. private async void CopyImage(object? sender, RoutedEventArgs args)
  43. {
  44. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  45. await clipboard.SetValueAsync(DataFormat.Bitmap, _defaultImage);
  46. }
  47. private async void PasteText(object? sender, RoutedEventArgs args)
  48. {
  49. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  50. {
  51. ClipboardContent.Text = await clipboard.TryGetTextAsync();
  52. }
  53. }
  54. private async void PasteImage(object? sender, RoutedEventArgs args)
  55. {
  56. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  57. {
  58. using var data = await clipboard.TryGetDataAsync();
  59. Bitmap? source = null;
  60. if (data != null)
  61. {
  62. source = await data!.TryGetValueAsync(DataFormat.Bitmap);
  63. }
  64. ClipboardImage.Source = source;
  65. }
  66. }
  67. private async void CopyFiles(object? sender, RoutedEventArgs args)
  68. {
  69. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  70. {
  71. var storageProvider = TopLevel.GetTopLevel(this)!.StorageProvider;
  72. var filesPath = (ClipboardContent.Text ?? string.Empty)
  73. .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
  74. if (filesPath.Length == 0)
  75. {
  76. return;
  77. }
  78. List<string> invalidFile = new(filesPath.Length);
  79. List<IStorageFile> files = new(filesPath.Length);
  80. for (int i = 0; i < filesPath.Length; i++)
  81. {
  82. var file = await storageProvider.TryGetFileFromPathAsync(filesPath[i]);
  83. if (file is null)
  84. {
  85. invalidFile.Add(filesPath[i]);
  86. }
  87. else
  88. {
  89. files.Add(file);
  90. }
  91. }
  92. if (invalidFile.Count > 0)
  93. {
  94. NotificationManager.Show(new Notification("Warning", "There is one o more invalid path.", NotificationType.Warning));
  95. }
  96. if (files.Count > 0)
  97. {
  98. var dataTransfer = _storedDataTransfer = new DataTransfer();
  99. foreach (var file in files)
  100. dataTransfer.Add(DataTransferItem.Create(DataFormat.File, file));
  101. await clipboard.SetDataAsync(dataTransfer);
  102. NotificationManager.Show(new Notification("Success", "Copy completed.", NotificationType.Success));
  103. }
  104. else
  105. {
  106. NotificationManager.Show(new Notification("Warning", "Any files to copy in Clipboard.", NotificationType.Warning));
  107. }
  108. }
  109. }
  110. private async void PasteFiles(object? sender, RoutedEventArgs args)
  111. {
  112. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  113. {
  114. var files = await clipboard.TryGetFilesAsync();
  115. ClipboardContent.Text = files != null ? string.Join(Environment.NewLine, files.Select(f => f.TryGetLocalPath() ?? f.Name)) : string.Empty;
  116. }
  117. }
  118. private async void GetFormats(object sender, RoutedEventArgs args)
  119. {
  120. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  121. {
  122. var formats = await clipboard.GetDataFormatsAsync();
  123. ClipboardContent.Text = string.Join(Environment.NewLine, formats);
  124. }
  125. }
  126. private async void CopyBinaryData(object? sender, RoutedEventArgs args)
  127. {
  128. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  129. {
  130. var dataTransfer = _storedDataTransfer = new DataTransfer();
  131. var bytes = new byte[10 * 1024 * 1024];
  132. new Random().NextBytes(bytes);
  133. dataTransfer.Add(DataTransferItem.Create(_customBinaryDataFormat, bytes));
  134. await clipboard.SetDataAsync(dataTransfer);
  135. }
  136. }
  137. private async void PasteBinaryData(object? sender, RoutedEventArgs args)
  138. {
  139. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  140. {
  141. var bytes = await clipboard.TryGetValueAsync(_customBinaryDataFormat);
  142. ClipboardContent.Text = bytes is null ? "<null>" : $"{bytes.Length} bytes";
  143. }
  144. }
  145. private async void Clear(object sender, RoutedEventArgs args)
  146. {
  147. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  148. {
  149. await clipboard.ClearAsync();
  150. }
  151. }
  152. protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
  153. {
  154. _clipboardLastDataObjectChecker.Start();
  155. base.OnAttachedToVisualTree(e);
  156. }
  157. protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
  158. {
  159. _clipboardLastDataObjectChecker.Stop();
  160. base.OnDetachedFromVisualTree(e);
  161. }
  162. private async void CheckLastDataObject(object? sender, EventArgs e)
  163. {
  164. if (_checkingClipboardDataTransfer)
  165. return;
  166. try
  167. {
  168. _checkingClipboardDataTransfer = true;
  169. var owns = false;
  170. if (TopLevel.GetTopLevel(this)?.Clipboard is { } clipboard)
  171. {
  172. var dataTransfer = await clipboard.TryGetInProcessDataAsync();
  173. owns = dataTransfer == _storedDataTransfer && dataTransfer is not null;
  174. }
  175. OwnsClipboardDataObject.Text = owns ? "Yes" : "No";
  176. OwnsClipboardDataObject.Foreground = owns ? Brushes.Green : Brushes.Red;
  177. }
  178. finally
  179. {
  180. _checkingClipboardDataTransfer = false;
  181. }
  182. }
  183. }
  184. }