csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
6.6 KiB
175 lines
6.6 KiB
using System;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Input;
|
|
using Avalonia.Markup.Xaml;
|
|
using Avalonia.Media;
|
|
using Avalonia.Media.Imaging;
|
|
using Avalonia.Platform;
|
|
|
|
using Avalonia.Platform.Storage;
|
|
|
|
namespace ControlCatalog.Pages
|
|
{
|
|
public partial class DragAndDropPage : UserControl
|
|
{
|
|
private readonly DataFormat<string> _customFormat =
|
|
DataFormat.CreateStringApplicationFormat("xxx-avalonia-controlcatalog-custom");
|
|
|
|
public DragAndDropPage()
|
|
{
|
|
InitializeComponent();
|
|
|
|
int textCount = 0;
|
|
|
|
SetupDnd(
|
|
"Text",
|
|
d => d.Add(DataTransferItem.Create(DataFormat.Text, $"Text was dragged {++textCount} times")),
|
|
DragDropEffects.Copy | DragDropEffects.Move | DragDropEffects.Link);
|
|
|
|
SetupDnd(
|
|
"Custom",
|
|
d => d.Add(DataTransferItem.Create(_customFormat, "Test123")),
|
|
DragDropEffects.Copy | DragDropEffects.Move);
|
|
|
|
SetupDnd(
|
|
"Files",
|
|
async d =>
|
|
{
|
|
if (Assembly.GetEntryAssembly()?.GetModules().FirstOrDefault()?.FullyQualifiedName is { } name &&
|
|
TopLevel.GetTopLevel(this) is { } topLevel &&
|
|
await topLevel.StorageProvider.TryGetFileFromPathAsync(name) is { } storageFile)
|
|
{
|
|
d.Add(DataTransferItem.Create(DataFormat.File, storageFile));
|
|
}
|
|
},
|
|
DragDropEffects.Copy);
|
|
|
|
SetupDnd(
|
|
"Bitmap",
|
|
d => d.Add(DataTransferItem.Create(DataFormat.Bitmap, new Bitmap(AssetLoader.Open(new Uri("avares://ControlCatalog/Assets/image1.jpg"))))),
|
|
DragDropEffects.Copy);
|
|
}
|
|
|
|
private void SetupDnd(string suffix, Action<DataTransfer> factory, DragDropEffects effects) =>
|
|
SetupDnd(
|
|
suffix,
|
|
o =>
|
|
{
|
|
factory(o);
|
|
return Task.CompletedTask;
|
|
},
|
|
effects);
|
|
|
|
private void SetupDnd(string suffix, Func<DataTransfer, Task> factory, DragDropEffects effects)
|
|
{
|
|
var dragMe = this.Get<Border>("DragMe" + suffix);
|
|
var dragState = this.Get<TextBlock>("DragState" + suffix);
|
|
|
|
async void DoDrag(object? sender, PointerPressedEventArgs e)
|
|
{
|
|
var dragData = new DataTransfer();
|
|
await factory(dragData);
|
|
|
|
var result = await DragDrop.DoDragDropAsync(e, dragData, effects);
|
|
switch (result)
|
|
{
|
|
case DragDropEffects.Move:
|
|
dragState.Text = "Data was moved";
|
|
break;
|
|
case DragDropEffects.Copy:
|
|
dragState.Text = "Data was copied";
|
|
break;
|
|
case DragDropEffects.Link:
|
|
dragState.Text = "Data was linked";
|
|
break;
|
|
case DragDropEffects.None:
|
|
dragState.Text = "The drag operation was canceled";
|
|
break;
|
|
default:
|
|
dragState.Text = "Unknown result";
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DragOver(object? sender, DragEventArgs e)
|
|
{
|
|
if (e.Source is Control c && c.Name == "MoveTarget")
|
|
{
|
|
e.DragEffects = e.DragEffects & (DragDropEffects.Move);
|
|
}
|
|
else
|
|
{
|
|
e.DragEffects = e.DragEffects & (DragDropEffects.Copy);
|
|
}
|
|
|
|
// Only allow if the dragged data contains text or filenames.
|
|
if (!e.DataTransfer.Contains(DataFormat.Text)
|
|
&& !e.DataTransfer.Contains(DataFormat.File)
|
|
&& !e.DataTransfer.Contains(DataFormat.Bitmap)
|
|
&& !e.DataTransfer.Contains(_customFormat))
|
|
e.DragEffects = DragDropEffects.None;
|
|
}
|
|
|
|
async void Drop(object? sender, DragEventArgs e)
|
|
{
|
|
if (e.Source is Control c && c.Name == "MoveTarget")
|
|
{
|
|
e.DragEffects = e.DragEffects & (DragDropEffects.Move);
|
|
}
|
|
else
|
|
{
|
|
e.DragEffects = e.DragEffects & (DragDropEffects.Copy);
|
|
}
|
|
|
|
if (e.DataTransfer.Contains(DataFormat.Text))
|
|
{
|
|
DropState.Content = e.DataTransfer.TryGetText();
|
|
}
|
|
else if (e.DataTransfer.Contains(DataFormat.File))
|
|
{
|
|
var files = e.DataTransfer.TryGetFiles() ?? [];
|
|
var contentStr = "";
|
|
|
|
foreach (var item in files)
|
|
{
|
|
if (item is IStorageFile file)
|
|
{
|
|
var content = await DialogsPage.ReadTextFromFile(file, 500);
|
|
contentStr += $"File {item.Name}:{Environment.NewLine}{content}{Environment.NewLine}{Environment.NewLine}";
|
|
}
|
|
else if (item is IStorageFolder folder)
|
|
{
|
|
var childrenCount = 0;
|
|
await foreach (var _ in folder.GetItemsAsync())
|
|
{
|
|
childrenCount++;
|
|
}
|
|
contentStr += $"Folder {item.Name}: items {childrenCount}{Environment.NewLine}{Environment.NewLine}";
|
|
}
|
|
}
|
|
DropState.Content = contentStr;
|
|
}
|
|
else if (e.DataTransfer.Contains(DataFormat.Bitmap))
|
|
{
|
|
var bitmap = e.DataTransfer.TryGetValue(DataFormat.Bitmap);
|
|
DropState.Content = new Image
|
|
{
|
|
Source = bitmap, Width = 400, Height = 300, Stretch = Stretch.Uniform
|
|
};
|
|
}
|
|
else if (e.DataTransfer.Contains(_customFormat))
|
|
{
|
|
DropState.Content = "Custom: " + e.DataTransfer.TryGetValue(_customFormat);
|
|
}
|
|
}
|
|
|
|
dragMe.PointerPressed += DoDrag;
|
|
|
|
AddHandler(DragDrop.DropEvent, Drop);
|
|
AddHandler(DragDrop.DragOverEvent, DragOver);
|
|
}
|
|
}
|
|
}
|
|
|