Last active
January 4, 2023 14:45
-
-
Save georg-jung/e6825e9cbafd0a5a13a8d2677ecfa634 to your computer and use it in GitHub Desktop.
Drop files behavior for WinUI 3.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.UI.Xaml; | |
using Windows.ApplicationModel.DataTransfer; | |
namespace App1.Helpers; | |
// based on https://stackoverflow.com/a/65266427/1200847 | |
public interface IFilesDropped | |
{ | |
void OnFilesDropped(string[] files); | |
} | |
public class DropFilesBehavior | |
{ | |
public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached( | |
"IsEnabled", typeof(bool), typeof(DropFilesBehavior), PropertyMetadata.Create(default(bool), OnIsEnabledChanged)); | |
public static readonly DependencyProperty FileDropTargetProperty = DependencyProperty.RegisterAttached( | |
"FileDropTarget", typeof(IFilesDropped), typeof(DropFilesBehavior), null); | |
public static void SetIsEnabled(DependencyObject element, bool value) | |
{ | |
element.SetValue(IsEnabledProperty, value); | |
} | |
public static bool GetIsEnabled(DependencyObject element) | |
{ | |
return (bool)element.GetValue(IsEnabledProperty); | |
} | |
public static void SetFileDropTarget(DependencyObject obj, IFilesDropped value) | |
{ | |
obj.SetValue(FileDropTargetProperty, value); | |
} | |
public static IFilesDropped GetFileDropTarget(DependencyObject obj) | |
{ | |
return (IFilesDropped)obj.GetValue(FileDropTargetProperty); | |
} | |
private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | |
{ | |
var fe = d as FrameworkElement ?? throw new InvalidOperationException(); | |
if ((bool)e.NewValue) | |
{ | |
fe.AllowDrop = true; | |
fe.Drop += OnDrop; | |
fe.DragOver += OnDragOver; | |
} | |
else | |
{ | |
fe.AllowDrop = false; | |
fe.Drop -= OnDrop; | |
fe.DragOver -= OnDragOver; | |
} | |
} | |
private static void OnDragOver(object sender, DragEventArgs e) | |
{ | |
e.AcceptedOperation = DataPackageOperation.Move; // or Link/Copy | |
e.Handled = true; | |
} | |
private static void OnDrop(object sender, DragEventArgs e) | |
{ | |
var dobj = (DependencyObject)sender; | |
var target = dobj.GetValue(FileDropTargetProperty); | |
var filesDropped = target switch | |
{ | |
IFilesDropped fd => fd, | |
null => throw new InvalidOperationException("File drop target is not set."), | |
_ => throw new InvalidOperationException($"Binding error, '{target.GetType().Name}' doesn't implement '{nameof(IFilesDropped)}'."), | |
}; | |
if (filesDropped == null) | |
{ | |
return; | |
} | |
var files = e.DataView.GetStorageItemsAsync().GetAwaiter().GetResult(); | |
if (files.Count == 0) | |
{ | |
return; | |
} | |
filesDropped.OnFilesDropped(files.Select(f => f.Path).ToArray()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Page | |
x:Class="App1.Views.MainPage" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
xmlns:helpers="using:App1.Helpers" | |
Background="{ThemeResource SolidBackgroundFillColorBaseBrush}" | |
mc:Ignorable="d"> | |
<Grid x:Name="ContentArea" helpers:DropFilesBehavior.IsEnabled="True" helpers:DropFilesBehavior.FileDropTarget="{x:Bind ViewModel}"> | |
</Grid> | |
</Page> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using App1.Helpers; | |
namespace App1.ViewModels; | |
public partial class ViewModel : ObservableRecipient, IFilesDropped | |
{ | |
public ViewModel() | |
{ | |
} | |
public void OnFilesDropped(string[] files) | |
{ | |
Debug.Print("---"); | |
foreach (var file in files) | |
{ | |
Debug.Print($"{file}"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment