DragAndDropPage.xaml.cs 5.5 KB

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