DragAndDropPage.xaml.cs 5.3 KB

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