DragAndDropPage.xaml.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using System;
  2. using System.Linq;
  3. using System.Reflection;
  4. using System.Threading.Tasks;
  5. using Avalonia.Controls;
  6. using Avalonia.Input;
  7. using Avalonia.Platform.Storage;
  8. namespace ControlCatalog.Pages
  9. {
  10. public partial class DragAndDropPage : UserControl
  11. {
  12. private readonly DataFormat<string> _customFormat =
  13. DataFormat.CreateStringApplicationFormat("xxx-avalonia-controlcatalog-custom");
  14. public DragAndDropPage()
  15. {
  16. InitializeComponent();
  17. int textCount = 0;
  18. SetupDnd(
  19. "Text",
  20. d => d.Add(DataTransferItem.Create(DataFormat.Text, $"Text was dragged {++textCount} times")),
  21. DragDropEffects.Copy | DragDropEffects.Move | DragDropEffects.Link);
  22. SetupDnd(
  23. "Custom",
  24. d => d.Add(DataTransferItem.Create(_customFormat, "Test123")),
  25. DragDropEffects.Copy | DragDropEffects.Move);
  26. SetupDnd(
  27. "Files",
  28. async d =>
  29. {
  30. if (Assembly.GetEntryAssembly()?.GetModules().FirstOrDefault()?.FullyQualifiedName is { } name &&
  31. TopLevel.GetTopLevel(this) is { } topLevel &&
  32. await topLevel.StorageProvider.TryGetFileFromPathAsync(name) is { } storageFile)
  33. {
  34. d.Add(DataTransferItem.Create(DataFormat.File, storageFile));
  35. }
  36. },
  37. DragDropEffects.Copy);
  38. }
  39. private void SetupDnd(string suffix, Action<DataTransfer> factory, DragDropEffects effects) =>
  40. SetupDnd(
  41. suffix,
  42. o =>
  43. {
  44. factory(o);
  45. return Task.CompletedTask;
  46. },
  47. effects);
  48. private void SetupDnd(string suffix, Func<DataTransfer, Task> factory, DragDropEffects effects)
  49. {
  50. var dragMe = this.Get<Border>("DragMe" + suffix);
  51. var dragState = this.Get<TextBlock>("DragState" + suffix);
  52. async void DoDrag(object? sender, PointerPressedEventArgs e)
  53. {
  54. var dragData = new DataTransfer();
  55. await factory(dragData);
  56. var result = await DragDrop.DoDragDropAsync(e, dragData, effects);
  57. switch (result)
  58. {
  59. case DragDropEffects.Move:
  60. dragState.Text = "Data was moved";
  61. break;
  62. case DragDropEffects.Copy:
  63. dragState.Text = "Data was copied";
  64. break;
  65. case DragDropEffects.Link:
  66. dragState.Text = "Data was linked";
  67. break;
  68. case DragDropEffects.None:
  69. dragState.Text = "The drag operation was canceled";
  70. break;
  71. default:
  72. dragState.Text = "Unknown result";
  73. break;
  74. }
  75. }
  76. void DragOver(object? sender, DragEventArgs e)
  77. {
  78. if (e.Source is Control c && c.Name == "MoveTarget")
  79. {
  80. e.DragEffects = e.DragEffects & (DragDropEffects.Move);
  81. }
  82. else
  83. {
  84. e.DragEffects = e.DragEffects & (DragDropEffects.Copy);
  85. }
  86. // Only allow if the dragged data contains text or filenames.
  87. if (!e.DataTransfer.Contains(DataFormat.Text)
  88. && !e.DataTransfer.Contains(DataFormat.File)
  89. && !e.DataTransfer.Contains(_customFormat))
  90. e.DragEffects = DragDropEffects.None;
  91. }
  92. async void Drop(object? sender, DragEventArgs e)
  93. {
  94. if (e.Source is Control c && c.Name == "MoveTarget")
  95. {
  96. e.DragEffects = e.DragEffects & (DragDropEffects.Move);
  97. }
  98. else
  99. {
  100. e.DragEffects = e.DragEffects & (DragDropEffects.Copy);
  101. }
  102. if (e.DataTransfer.Contains(DataFormat.Text))
  103. {
  104. DropState.Text = e.DataTransfer.TryGetText();
  105. }
  106. else if (e.DataTransfer.Contains(DataFormat.File))
  107. {
  108. var files = e.DataTransfer.TryGetFiles() ?? [];
  109. var contentStr = "";
  110. foreach (var item in files)
  111. {
  112. if (item is IStorageFile file)
  113. {
  114. var content = await DialogsPage.ReadTextFromFile(file, 500);
  115. contentStr += $"File {item.Name}:{Environment.NewLine}{content}{Environment.NewLine}{Environment.NewLine}";
  116. }
  117. else if (item is IStorageFolder folder)
  118. {
  119. var childrenCount = 0;
  120. await foreach (var _ in folder.GetItemsAsync())
  121. {
  122. childrenCount++;
  123. }
  124. contentStr += $"Folder {item.Name}: items {childrenCount}{Environment.NewLine}{Environment.NewLine}";
  125. }
  126. }
  127. DropState.Text = contentStr;
  128. }
  129. else if (e.DataTransfer.Contains(_customFormat))
  130. {
  131. DropState.Text = "Custom: " + e.DataTransfer.TryGetValue(_customFormat);
  132. }
  133. }
  134. dragMe.PointerPressed += DoDrag;
  135. AddHandler(DragDrop.DropEvent, Drop);
  136. AddHandler(DragDrop.DragOverEvent, DragOver);
  137. }
  138. }
  139. }